• [Sdoi2009]Elaxia的路线


    Description

    最近,Elaxia和w**的关系特别好,他们很想整天在一起,但是大学的学习太紧张了,他们 必须合理地安排两个人在一起的时间。Elaxia和w**每天都要奔波于宿舍和实验室之间,他们 希望在节约时间的前提下,一起走的时间尽可能的长。 现在已知的是Elaxia和w**所在的宿舍和实验室的编号以及学校的地图:地图上有N个路 口,M条路,经过每条路都需要一定的时间。 具体地说,就是要求无向图中,两对点间最短路的最长公共路径。

    Input

    第一行:两个整数N和M(含义如题目描述)。 第二行:四个整数x1、y1、x2、y2(1 ≤ x1 ≤ N,1 ≤ y1 ≤ N,1 ≤ x2 ≤ N,1 ≤ ≤ N),分别表示Elaxia的宿舍和实验室及w**的宿舍和实验室的标号(两对点分别 x1,y1和x2,y2)。 接下来M行:每行三个整数,u、v、l(1 ≤ u ≤ N,1 ≤ v ≤ N,1 ≤ l ≤ 10000),表 u和v之间有一条路,经过这条路所需要的时间为l。 出出出格格格式式式::: 一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)。

    Output

    一行,一个整数,表示每天两人在一起的时间(即最长公共路径的长度)

    Sample Input

    9 10
    1 6 7 8
    1 2 1
    2 5 2
    2 3 3
    3 4 2
    3 9 5
    4 5 3
    4 6 4
    4 7 2
    5 8 1
    7 9 1

    Sample Output

    3

    HINT

    对于30%的数据,N ≤ 100;
    对于60%的数据,N ≤ 1000;
    对于100%的数据,N ≤ 1500,输入数据保证没有重边和自环。

    分别以x1,y1,x2,y2为起点,做4次SPFA

    分别算出dist[1~4][x]

    那么我们可以找到他们各自最短路中相同的边

    只要同时满足:

    dist[1][u]+w(u,v)+dist[2][v]=dist[1][y1]

    dist[3][u]+w(u,v)+dist[4][v]=dist[3][y2]

    那么就说明,这条边同时处于两人的最短路上

    然后将这些边建一个新图,可以保证无环

    最后拓扑排序求出最长的链

    但是,这道题隐藏了一个情况:

    从y2~x2的w**与从x1~y1的Elaxia在边上相遇,也就是相向而行走一条边,也算共同走了这一条

    也就是说,我们要将w**起点终点反转,重新建边和拓扑

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<algorithm>
      4 #include<cstring>
      5 #include<queue>
      6 using namespace std;
      7 struct Node
      8 {
      9   int next,to,dis;
     10 }edge[2000001],edge2[2000001];
     11 int head[2001],num,head2[2001],num2,dist[5][2001],f[2001],n,d[2001],ans,m;
     12 int s1,s2,t1,t2;
     13 bool vis[2001];
     14 void add(int u,int v,int w)
     15 {
     16   num++;
     17   edge[num].next=head[u];
     18   head[u]=num;
     19   edge[num].to=v;
     20   edge[num].dis=w;
     21 }
     22 void add_Top(int u,int v,int w)
     23 {
     24   num2++;
     25   edge2[num2].next=head2[u];
     26   head2[u]=num2;
     27   edge2[num2].to=v;
     28   edge2[num2].dis=w;
     29 }
     30 void SPFA(int S,int T,int p)
     31 {int i;
     32   queue<int>Q;
     33   memset(dist[p],127/3,sizeof(dist[p]));
     34   dist[p][S]=0;
     35   Q.push(S);
     36   while (Q.empty()==0)
     37     {
     38       int u=Q.front();
     39       Q.pop();
     40       vis[u]=0;
     41       for (i=head[u];i;i=edge[i].next)
     42     {
     43       int v=edge[i].to;
     44       if (dist[p][v]>dist[p][u]+edge[i].dis)
     45         {
     46           dist[p][v]=dist[p][u]+edge[i].dis;
     47           if (vis[v]==0)
     48         {vis[v]=1;
     49           Q.push(v);
     50         }
     51         }
     52     }
     53     }
     54 }
     55 void Top_sort()
     56 {int i;
     57   queue<int>Q;
     58   memset(f,0,sizeof(f));
     59   for (i=1;i<=n;i++)
     60     if (d[i]==0) Q.push(i),f[i]=0;
     61   while (Q.empty()==0)
     62     {
     63       int u=Q.front();
     64       Q.pop();
     65       ans=max(ans,f[u]);
     66       for (i=head2[u];i;i=edge2[i].next)
     67     {
     68       int v=edge2[i].to;
     69       d[v]--;
     70       f[v]=max(f[v],f[u]+edge2[i].dis);
     71       if (d[v]==0)
     72         {
     73           Q.push(v);
     74         }
     75     }
     76     }
     77 }
     78 int main()
     79 {int i,u,v,w,j;
     80   cin>>n>>m;
     81   cin>>s1>>t1>>s2>>t2;
     82   for (i=1;i<=m;i++)
     83     {
     84       scanf("%d%d%d",&u,&v,&w);
     85       add(u,v,w);
     86       add(v,u,w);
     87     }
     88   SPFA(s1,t1,1);
     89   SPFA(t1,s1,2);
     90   SPFA(s2,t2,3);
     91   SPFA(t2,s2,4);
     92   for (i=1;i<=n;i++)
     93     {
     94       for (j=head[i];j;j=edge[j].next)
     95     {
     96       int v=edge[j].to;
     97       if (dist[1][i]+edge[j].dis+dist[2][v]!=dist[1][t1]) continue;
     98       if (dist[3][i]+edge[j].dis+dist[4][v]!=dist[3][t2]) continue;
     99       add_Top(i,v,edge[j].dis);
    100       d[v]++;
    101     }
    102     }
    103   Top_sort();
    104   SPFA(t2,s2,3);
    105   SPFA(s2,t2,4);
    106   memset(d,0,sizeof(d));
    107   memset(head2,0,sizeof(head2));
    108   for (i=1;i<=n;i++)
    109     {
    110       for (j=head[i];j;j=edge[j].next)
    111     {
    112       int v=edge[j].to;
    113       if (dist[1][i]+edge[j].dis+dist[2][v]!=dist[1][t1]) continue;
    114       if (dist[3][i]+edge[j].dis+dist[4][v]!=dist[3][s2]) continue;
    115       add_Top(i,v,edge[j].dis);
    116       d[v]++;
    117     }
    118     }
    119   Top_sort();
    120   cout<<ans;
    121 }
  • 相关阅读:
    Mac音频播放
    Mac开发
    CoreFoundation对象的内存管理
    蓝牙收发数据长度的问题
    Android音视频之AudioTrack播放音频(二)
    Android音视频之AudioRecord录音(一)
    wav格式文件、pcm数据
    自定义view 波浪效果
    git 常用命令
    markdown 基本语法
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7705060.html
Copyright © 2020-2023  润新知