NYOJ 247
View Code
1 /* 2 思路: 3 利用最短路的变形 4 分别从起点搜一次 5 从终点搜一次 6 从起点搜出从起点到达各点的最小值 7 从终点搜出从终点到达各点的最大值(所有可以到达的点) 8 9 主要思想是: 10 从 1 到 i 再从 i 到 n 11 从 1 到 i 时 路径是正着存的 12 13 从i 到 n 时我们把路径反着存一次 14 变成求 从 n 到 i 了(此处最重要) 15 */ 16 #include<iostream> 17 #include<cstdio> 18 #include<cstring> 19 #include<queue> 20 #define qmax(a,b) ((a)>(b))?(a):(b) 21 #define qmin(a,b) ((a)<(b))?(a):(b) 22 using namespace std; 23 24 const int roadnum=500001; 25 const int citynum=100001; 26 struct node 27 { 28 int e; 29 int next; 30 }edge[roadnum*2]; 31 32 int k1[citynum],k2[citynum]; 33 bool flag1[citynum],flag2[citynum]; 34 int maxval[citynum],minval[citynum]; 35 int n,m; 36 int k=0; 37 queue <int> q; 38 39 void ADD(int from,int to) 40 { 41 edge[k].e=to; 42 edge[k].next=k1[from]; 43 k1[from]=k++; 44 45 edge[k].e=from; 46 edge[k].next=k2[to]; 47 k2[to]=k++; 48 } 49 50 void init() 51 { 52 int i,x,y,z; 53 memset(flag1,0,sizeof(flag1)); 54 memset(flag2,0,sizeof(flag2)); 55 memset(k1,-1,sizeof(k1));//从起点搜索用 56 memset(k2,-1,sizeof(k2));//从终点搜索用 57 for(i=1;i<=n;++i) 58 { 59 scanf("%d",&minval[i]); 60 maxval[i]=minval[i]; 61 } 62 while(m--) 63 { 64 scanf("%d%d%d",&x,&y,&z); 65 ADD(x,y); 66 if(2==z)ADD(y,x); 67 } 68 } 69 70 int spfa() 71 { 72 int x,y,i; 73 while(!q.empty())q.pop(); 74 q.push(1); 75 flag1[1]=1; 76 while(!q.empty())// 这个while() 控制从 从起点 可以到达的所有点可以取的最小值 77 { 78 x = q.front(); 79 q.pop(); 80 for(i=k1[x];i!=-1;i=edge[i].next) 81 { 82 y= edge[i].e; 83 minval[y]=qmin(minval[x],minval[y]); 84 if(!flag1[y]) 85 { 86 q.push(y); 87 flag1[y]=1; 88 } 89 } 90 } 91 92 q.push(n); 93 flag2[n]=1; 94 while(!q.empty())// 因为路径反着存了一次 我们从终点 逆向搜回去 可以到达各点的最大值 95 { //相当于从各点走到终点的最大值(因为路径反存了一次) 96 x = q.front(); 97 q.pop(); 98 for(i=k2[x];i!=-1;i=edge[i].next) 99 { 100 y = edge[i].e; 101 maxval[y]=qmax(maxval[x],maxval[y]); 102 if(!flag2[y]) 103 { 104 q.push(y); 105 flag2[y]=1; 106 } 107 } 108 } 109 int te=0; 110 for(i=1;i<=n;++i) 111 if(flag1[i] && flag2[i] && maxval[i]-minval[i]>te)// flag1[i]!=0表明从起点可以到这个点 112 te=maxval[i]-minval[i]; //flag2[i]!=0表明从点 i 可以到达终点 113 return te; 114 } 115 116 int main() 117 { 118 while(EOF != scanf("%d%d",&n,&m)) 119 { 120 init(); 121 printf("%d\n",spfa()); 122 } 123 return 0; 124 }