题意:
- 在一张节点有权的图上找出一条从1到N的路径,使路径上的两点A , B的差值权最大(两个点互相经过)。
题解:
- 考虑将这张图中双向路看成两条方向相反的单向道路,并把这张图看成有向图。
- 建立一张反图,从1->N和N->1分别跑最短路,求出每个点能经过的最小权与最大权。
- 最后枚举每个结点,更新出点的最小权与最大权的最大差值即可。
代码片:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <queue> 6 #define Inf 0x7fffff 7 const int Maxx = 500000; 8 9 using namespace std; 10 11 int Head[2*Maxx+1] , Next[2*Maxx+1] , Value[Maxx+1]; 12 int Heads[2*Maxx+1] , Nexts[2*Maxx+1]; 13 int F[Maxx+1] , D[Maxx+1] , T1[Maxx+1] , T2[Maxx+1]; 14 int N , M , Sum = 0 , Num = 0 , X , Y , Z; 15 struct Yuns{ 16 int X; 17 int Y; 18 }Ver[2*Maxx+1]; 19 struct Yunss{ 20 int X; 21 int Y; 22 }Vers[2*Maxx+1]; 23 priority_queue < pair<int , int> > Q1; 24 priority_queue < pair<int , int> > Q2; 25 26 int Read(){ 27 28 int x = 0; 29 char c = getchar(); 30 while(c < ‘0‘ || c > ‘9‘) c = getchar(); 31 while(c >= ‘0‘ && c <= ‘9‘) x = x*10 + c-‘0‘ , c = getchar(); 32 return x; 33 34 } 35 36 void Add(int X , int Y){ 37 Ver[++Sum].X = X; 38 Ver[Sum].Y = Y; 39 Next[Sum] = Head[X]; 40 Head[X] = Sum; 41 return; 42 } 43 44 void Add_T(int X , int Y){ 45 Vers[++Num].X = X; 46 Vers[Num].Y = Y; 47 Nexts[Num] = Heads[X]; 48 Heads[X] = Num; 49 return; 50 } 51 52 void Dijkstra_1(){ 53 F[1] = Value[1]; 54 Q1.push(make_pair(F[1] , 1)); 55 while(Q1.size()){ 56 int Tag = Q1.top().second; 57 Q1.pop(); 58 if (T1[Tag]) continue; 59 T1[Tag] = 1; 60 for (int i = Head[Tag] ; i ; i = Next[i]){ 61 int Y = Ver[i].Y; 62 F[Y] = min(F[Tag] , Value[Y]); 63 Q1.push(make_pair(F[Y] , Y)); 64 } 65 } 66 return; 67 } 68 69 void Dijkstra_2(){ 70 D[N] = Value[N]; 71 Q2.push(make_pair(D[N] , N)); 72 while(Q2.size()){ 73 int Tag = Q2.top().second; 74 Q2.pop(); 75 if (T2[Tag]) continue; 76 T2[Tag] = 1; 77 for (int i = Heads[Tag] ; i ; i = Nexts[i]){ 78 int Y = Vers[i].Y; 79 D[Y] = max(D[Tag] , Value[Y]); 80 Q2.push(make_pair(D[Y] , Y)); 81 } 82 } 83 return; 84 } 85 86 void In_Work(){ 87 88 cin >> N >> M; 89 for (int i = 1 ; i <= N ; i++) Value[i] = Read(); 90 for (int i = 1 ; i <= M ; i++){ 91 X = Read() , Y = Read() , Z = Read(); 92 Add(X , Y); 93 Add_T(Y , X); 94 if (Z == 2) Add(Y , X) , Add_T(X , Y); 95 } 96 97 for(int i = 1 ; i <= N ; i++) F[i] = Inf; 98 for(int i = 1 ; i <= N ; i++) D[i] = Inf; 99 Dijkstra_1(); 100 Dijkstra_2(); 101 102 } 103 104 void In_Out(){ 105 106 int Ans = -1; 107 for(int i = 1 ; i <= N ; i++) 108 if (D[i]!=Inf && F[i]!=Inf) 109 Ans = max(Ans , D[i]-F[i]); 110 cout << Ans; 111 112 } 113 void In_File(){ 114 // freopen("dance.in" , "r" , stdin); 115 // freopen("dance.out" , "w" , stdout); 116 } 117 118 int main(){ 119 120 In_File(); 121 122 In_Work(); 123 124 In_Out(); 125 126 return 0; 127 128 }
最优贸易
原文地址:https://www.cnblogs.com/Yuns/p/10387430.html
时间: 2024-10-16 07:47:36