• 图论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的最短路的边
    之后同样在这些边求出并行走,反向走的最长公共路径  

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #define endl '\n'
    12. #define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
    13. #define ms(x,y) memset(x,y,sizeof x);
    14. #define YES cout<<"YES"<<'\n';
    15. #define NO  cout<<"NO"<<'\n';
    16. #define fr(i,z,n) for(int i = z;i <= n; i++)
    17. #define fer(i,x)   for(int i=e.head[x];i;i=e.next[i])
    18. #define ufr(i,n,z) for(int i = n;i >= z; i--)
    19. #define int long long 
    20. typedef long long ll;
    21. const ll N = 1e6 + 10, inf = 1e18;
    22. const ll mod = 1e9 + 7;
    23. using namespace std;
    24. template<size_t size>
    25. struct Road {
    26.     int to[size], next[size], head[size], cnt = 1;
    27.     ll w[size];
    28.     void add(int x, int y, ll ww) {
    29.         to[cnt] = y;
    30.         w[cnt] = ww;
    31.         next[cnt] = head[x];
    32.         head[x] = cnt++;
    33.     }
    34.     void clear(int n) {
    35.         for (int i = 0; i <= n; i++) {
    36.             head[i] = 0;
    37.         }
    38.         cnt = 1;
    39.     }
    40. };
    41. Roade;
    42. int dis[4][N];
    43. bool vis[N];
    44. int n, m;
    45. int ok[N], in[N];
    46. int f[N], g[N];                  //记录反向走和并行走两种情况
    47. void spfa(int u,int k) {
    48.     fr(i, 1, n) {
    49.         dis[k][i] = 0x3f3f3f3f;
    50.         vis[i] = 0;
    51.     }
    52.     vis[u] = 1;
    53.     dis[k][u] = 0;
    54.     queue<int>q;
    55.     q.push(u);
    56.     while (!q.empty()) {
    57.         int x = q.front();
    58.         q.pop();
    59.         vis[x] = 0;
    60.         fer(i, x) {
    61.             int v = e.to[i];
    62.             int w = e.w[i];
    63.             if (dis[k][x] + w < dis[k][v]) {
    64.                 dis[k][v] = dis[k][x] + w;
    65.                 if (!vis[v]) {
    66.                     q.push(v);
    67.                     vis[v] = 1;
    68.                 }
    69.             }
    70.         }
    71.     }
    72. }
    73. void solve() {
    74.     cin >> n >> m;
    75.     int s1, t1, s2, t2;
    76.     cin >> s1 >> t1 >> s2 >> t2;    
    77.     fr(i, 1, m) {
    78.         int x, y,w;
    79.         cin >> x >> y >> w;
    80.         e.add(x, y, w);
    81.         e.add(y, x, w);
    82.     }
    83.     spfa(s1, 0); spfa(t1, 1);          //最短路
    84.     spfa(s2, 2); spfa(t2, 3);
    85.     fr(u, 1, n) {                       //选出最短路中的有用边
    86.         fer(i, u) {
    87.             int w = e.w[i];
    88.             int v = e.to[i];
    89.             if ((dis[0][u] + w+dis[1][v])==dis[0][t1]) {    
    90.                 //s1到u的最短路+u到v的距离+v到t1的最短路==s1到t1的最短路
    91.                 ok[i] = 1;
    92.                 in[v]++;
    93.             }
    94.         }
    95.     }
    96.     int ans = 0;
    97.     queue<int>q;
    98.     q.push(s1);
    99.     while (!q.empty()) {               //拓扑排序
    100.         int u = q.front();
    101.         q.pop();
    102.         ans = max({ g[u], f[u],ans });
    103.         fer(i, u) {
    104.             if (ok[i]) {               //有用边
    105.                 int v = e.to[i];
    106.                 int w = e.w[i];
    107.                 in[v]--;
    108.                 if (in[v] == 0) {
    109.                     q.push(v);
    110.                 }
    111.                 if ((dis[2][u] + w + dis[3][v]) == dis[2][t2]) {     //筛出有用边
    112.                     //从s2到u的最短路+u到v的距离+v到t2的最短路=s2到t2的最短路
    113.                     //并行走
    114.                     g[v] = max(g[v], g[u] + w);
    115.  
    116.                 }
    117.                 if((dis[3][u] + w + dis[2][v]) == dis[2][t2]) {
    118.                     //从t2到u的最短路+u到v的距离+v到s2的最短路=s2到t2的最短路
    119.                     //反向走
    120.                     f[v] = max(f[v], f[u] + w);
    121.                 }
    122.             }
    123.         }
    124.     }
    125.     cout << ans << '\n';
    126. }
    127. signed main()
    128. {
    129.     ios;
    130.     int t = 1;
    131.     //cin >> t;
    132.     while (t--) {
    133.         solve();
    134.     }
    135. }

  • 相关阅读:
    Python MQTT客户端 paho-mqtt
    【CMU15-445 Part-9】Multi-Threaded Index Concurrency Control
    Linux--网络概念
    【Java基础】Java关键字、字面量和变量—21天学习计划打卡第二天
    JavaScript 变量提升的作用
    数据结构第三遍补充(图的应用)
    【3D建模制作技巧分享】zbrush贴图映射小技巧
    Flink学习25:窗口计算函数
    2023 “华为杯” 中国研究生数学建模竞赛(B题)深度剖析|数学建模完整代码+建模过程全解全析
    模式匹配——从BF算法到KMP算法
  • 原文地址:https://blog.csdn.net/m0_75027890/article/details/134367370