洛谷 P1073 最优贸易

建模。本题是让我们在一张图上找到一条从1到N的道路,使路径上能选出两个点p, q(先p后q),且 q 的权值- p 的权值最大。

考虑用最短路算法分别算出:

1.从起点到某个点的路径上的最小的 p ;

2.从终点到某个点最大的 q。

分别记为 d1 和 d2 。

把每个节点看做两条路径相交的点。于是,枚举每个节点 x, 用 d2[ x ] -  d1[ x ] 更新答案即可。

注意用最短路算法求解问题(2)时需要用到反图。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef pair<int, int> P;
  4 const int MAXN = 100000 + 20;
  5 const int MAXM = 500000 + 20;
  6 const int INF = 0x3f3f3f3f;
  7 
  8 int N, M, C[MAXN];
  9 
 10 inline int read()
 11 {
 12     int x = 0; char ch = getchar();
 13     while(!isdigit(ch)) ch = getchar();
 14     while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
 15     return x;
 16 }
 17 
 18 namespace dij
 19 {
 20     vector<int> g[MAXN], rg[MAXN];
 21     int d1[MAXN], d2[MAXN];
 22 
 23     void init()
 24     {
 25         memset(d1, 0x3f, sizeof(d1));
 26         memset(d2, 0, sizeof(d2));
 27     }
 28 
 29     inline void addedge(int u, int v, int t)
 30     {
 31         if(t == 1) 
 32         {
 33             g[u].push_back(v);
 34             rg[v].push_back(u);
 35         }
 36         else
 37         {
 38             g[u].push_back(v);
 39             g[v].push_back(u);
 40             rg[u].push_back(v);
 41             rg[v].push_back(u);
 42         }
 43     }
 44 
 45     void dijkstra(int s)
 46     {
 47         priority_queue<P, vector<P>, greater<P> > q;
 48         memset(d1, 0x3f, sizeof(d1));
 49         d1[s] = C[s];
 50         q.push(P(C[s], s));
 51 
 52         while(!q.empty())
 53         {
 54             P p = q.top(); q.pop();
 55             int u = p.second;
 56             if(d1[u] < p.first) continue;
 57 
 58             for(int i = 0; i < (int) g[u].size(); i++)
 59             {
 60                 int v = g[u][i];
 61                 if(d1[v] > min(d1[u], C[v]))
 62                 {
 63                     d1[v] = min(d1[u], C[v]);
 64                     q.push(P(d1[v], v));
 65                 }
 66             }
 67         }
 68     }//
 69 
 70     void rdijkstra(int s)
 71     {
 72         priority_queue<P, vector<P>, less<P> > q;
 73         memset(d2, 0, sizeof(d2));
 74 
 75         d2[s] = C[s];
 76         q.push(P(C[s], s));
 77 
 78         while(!q.empty())
 79         {
 80             P p = q.top(); q.pop();
 81             int u = p.second;
 82             if(d2[u] > p.first) continue;
 83 
 84             for(int i = 0; i < (int) rg[u].size(); i++)
 85             {
 86                 int v = rg[u][i];
 87                 if(d2[v] < max(d2[u], C[v]))
 88                 {
 89                     d2[v] = max(d2[u], C[v]);
 90                     q.push(P(d2[v], v));
 91                 }
 92             }
 93         }
 94     }
 95 
 96 }
 97 
 98 int main()
 99 {
100     //freopen("p1073.txt", "r", stdin);
101     cin>>N>>M;
102     for(int i = 1; i <= N; i++)
103         C[i] = read();
104 
105     using namespace dij;
106     int u, v;
107     for(int i = 1; i <= M; i++)
108     {
109         u = read(), v = read();
110         addedge(u, v, read());
111     }
112 
113     dijkstra(1);
114     rdijkstra(N);
115 
116 //    for(int i = 1; i <= N; i++)
117 //        cout<<d1[i]<<" "<<d2[i]<<endl;
118 //    puts("");
119     int ans = -1;
120     for(int i = 1; i <= N; i++)
121         {
122             ans = max(ans, d2[i] - d1[i]);
123 //            cout<<i<<" "<<d2[i] - d1[i]<<endl;
124         }
125 
126     cout<<ans<<endl;
127     return 0;
128 }

猜你喜欢

转载自www.cnblogs.com/wsmrxc/p/8985768.html