图论2023.11.12

二分图--匈牙利算法匹配

P2319 [HNOI2006] 超级英雄

P1894[USACO4.2] 完美的牛栏The Perfect Stall

P2071 座位安排

分层图

P4822 [BJWC2012] 冻结

P4568[JLOI2011] 飞行路线

P2939 [USACO09FEB] Revamping Trails G

最短路

P2149[SDOI2009] Elaxia的路线

Elaxia 和 w** 的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们必须合理地安排两个人在一起的时间。

Elaxia 和 w** 每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。

现在已知的是 Elaxia 和 w** 所在的宿舍和实验室的编号以及学校的地图:

地图上有n 个路口,m 条路,经过每条路都需要一定的时间

题意:求无向图中,两对点间最短路的最长公共路径的长度

筛出最短路的边

思路:分别求出从s1,t1,s2,t2出发的最短路,筛出s1到t1的最短路的边

之后同样在这些边求出并行走,反向走的最长公共路径

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<math.h>
#include<map>
#include<vector>
#include<stack>
#define endl '\n'
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
#define ms(x,y) memset(x,y,sizeof x);
#define YES cout<<"YES"<<'\n';
#define NO  cout<<"NO"<<'\n';
#define fr(i,z,n) for(int i = z;i <= n; i++)
#define fer(i,x)   for(int i=e.head[x];i;i=e.next[i])
#define ufr(i,n,z) for(int i = n;i >= z; i--)
#define int long long 
typedef long long ll;
const ll N = 1e6 + 10, inf = 1e18;
const ll mod = 1e9 + 7;
using namespace std;
template<size_t size>
struct Road {
    int to[size], next[size], head[size], cnt = 1;
    ll w[size];
    void add(int x, int y, ll ww) {
        to[cnt] = y;
        w[cnt] = ww;
        next[cnt] = head[x];
        head[x] = cnt++;
    }
    void clear(int n) {
        for (int i = 0; i <= n; i++) {
            head[i] = 0;
        }
        cnt = 1;
    }
};
Road<N>e;
int dis[4][N];
bool vis[N];
int n, m;
int ok[N], in[N];
int f[N], g[N];                  //记录反向走和并行走两种情况
void spfa(int u,int k) {
    fr(i, 1, n) {
        dis[k][i] = 0x3f3f3f3f;
        vis[i] = 0;
    }
    vis[u] = 1;
    dis[k][u] = 0;
    queue<int>q;
    q.push(u);
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        vis[x] = 0;
        fer(i, x) {
            int v = e.to[i];
            int w = e.w[i];
            if (dis[k][x] + w < dis[k][v]) {
                dis[k][v] = dis[k][x] + w;
                if (!vis[v]) {
                    q.push(v);
                    vis[v] = 1;
                }
            }
        }
    }
}
void solve() {
    cin >> n >> m;
    int s1, t1, s2, t2;
    cin >> s1 >> t1 >> s2 >> t2;    
    fr(i, 1, m) {
        int x, y,w;
        cin >> x >> y >> w;
        e.add(x, y, w);
        e.add(y, x, w);
    }
    spfa(s1, 0); spfa(t1, 1);          //最短路
    spfa(s2, 2); spfa(t2, 3);
    fr(u, 1, n) {                       //选出最短路中的有用边
        fer(i, u) {
            int w = e.w[i];
            int v = e.to[i];
            if ((dis[0][u] + w+dis[1][v])==dis[0][t1]) {    
                //s1到u的最短路+u到v的距离+v到t1的最短路==s1到t1的最短路
                ok[i] = 1;
                in[v]++;
            }
        }
    }
    int ans = 0;
    queue<int>q;
    q.push(s1);
    while (!q.empty()) {               //拓扑排序
        int u = q.front();
        q.pop();
        ans = max({ g[u], f[u],ans });
        fer(i, u) {
            if (ok[i]) {               //有用边
                int v = e.to[i];
                int w = e.w[i];
                in[v]--;
                if (in[v] == 0) {
                    q.push(v);
                }
                if ((dis[2][u] + w + dis[3][v]) == dis[2][t2]) {     //筛出有用边
                    //从s2到u的最短路+u到v的距离+v到t2的最短路=s2到t2的最短路
                    //并行走
                    g[v] = max(g[v], g[u] + w);
 
                }
                if((dis[3][u] + w + dis[2][v]) == dis[2][t2]) {
                    //从t2到u的最短路+u到v的距离+v到s2的最短路=s2到t2的最短路
                    //反向走
                    f[v] = max(f[v], f[u] + w);
                }

            }
        }
    }
    cout << ans << '\n';
}

signed main()
{
    ios;
    int t = 1;
    //cin >> t;
    while (t--) {
        solve();
    }
}
相关推荐
闻缺陷则喜何志丹12 天前
【并集查找】P10729 [NOISG 2023 Qualification] Dolls|普及+
c++·算法·图论·洛谷·并集查找
CodeWithMe12 天前
【Algorithm】图论入门
c++·图论
东方芷兰14 天前
Leetcode 刷题记录 13 —— 图论
算法·leetcode·图论
蒙奇D索大16 天前
【数据结构】图论实战:DAG空间压缩术——42%存储优化实战解析
数据结构·笔记·学习·考研·图论·改行学it
蒙奇D索大19 天前
【数据结构】图论最短路圣器:Floyd算法如何用双矩阵征服负权图?
数据结构·算法·矩阵·图论·图搜索算法
芜湖xin20 天前
【题解-洛谷】B4292 [蓝桥杯青少年组省赛 2022] 路线
算法·图论·bfs·图的遍历
LunaGeeking21 天前
重要的城市(图论 最短路)
c++·算法·编程·图论·最短路·floyd
闻缺陷则喜何志丹21 天前
【强连通分量 拓扑序】P9431 [NAPC-#1] Stage3 - Jump Refreshers|普及+
c++·算法·图论·拓扑序·洛谷·强连通分量
蒙奇D索大24 天前
【数据结构】图论最短路径算法深度解析:从BFS基础到全算法综述
数据结构·算法·图论·广度优先·图搜索算法
计信金边罗1 个月前
是否存在路径(FIFOBB算法)
算法·蓝桥杯·图论