1. 程式人生 > >hdu 5521 Meeting(最短路)

hdu 5521 Meeting(最短路)

names n) can style air ima pid hid con

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=5521

技術分享圖片


題意:有1-n共n個點,給出m個塊(完全圖),並知道塊內各點之間互相到達花費時間均為ti。已知兩人分別在點1和點n,求在哪些點相遇能使得花費時間最短。


題解:顯然先想到從點1和點n分別求最短路,然後枚舉點找出哪些點是相遇花費時間最少的。但是這題邊太多了,假設一個完全圖裏有x個點,那邊就有x*(x-1)/2條了,必須化簡其邊。一個可行的辦法是給每個完全圖增加兩個點,分別為入點和出點,入點向其中的點連邊,其中的點再向出點連邊,權均為0,出點向入點連邊,權為ti,邊數就化簡為2*x了。

代碼實現:
技術分享圖片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const ll INF = 1e18;
 5 const int N = 2100010;
 6 const int M = 2100010;
 7 struct edge {
 8     int to;
 9     ll cost;
10     edge(int _to, ll _cost):to(_to),cost(_cost){}
11 };
12 typedef pair<ll, int
> P;// first是最短距離,second是頂點的編號 13 int V; 14 vector<edge>G[N]; 15 ll d[2][N];//點1 和 點n 到達其他點的最短時間 16 void dij(int id, int s) { 17 priority_queue<P, vector<P>, greater<P> > que; 18 for(int i = 0; i <= V; ++i) d[id][i] = INF; 19 d[id][s] = 0; 20 que.push(P(0
, s)); 21 22 while(!que.empty()) { 23 P p = que.top(); que.pop(); 24 int v = p.second; 25 if(d[id][v] < p.first) continue; 26 int num = G[v].size(); 27 for(int i = 0; i < num; ++i) { 28 edge e = G[v][i]; 29 if(d[id][e.to] > d[id][v] + e.cost) { 30 d[id][e.to] = d[id][v] + e.cost; 31 que.push(P(d[id][e.to], e.to)); 32 } 33 } 34 } 35 } 36 int main() { 37 int k, T, t, n, m, i, s, x, u, v; 38 scanf("%d", &T); 39 for(k = 1; k <= T; ++k) { 40 for(i = 0; i < N; ++i) G[i].clear(); 41 scanf("%d%d", &n, &m);//點數,集合(完全圖)數目 42 for(i = 1; i <= 2*m; i += 2) { 43 u = n+i;//入點 44 v = n+i+1;//出點 45 scanf("%d%d", &t, &s);//時間,集合中點數 46 while(s--) { 47 scanf("%d", &x); 48 G[u].push_back(edge(x, 0)); 49 G[x].push_back(edge(v, 0)); 50 } 51 G[v].push_back(edge(u, t)); 52 } 53 V = n+2*m; 54 dij(0, 1); 55 dij(1, n); 56 /* 57 puts("-----------------"); 58 for(i = 1; i <= n; ++i) { 59 printf("%lld, %lld\n", d[0][i], d[1][i]); 60 } 61 puts("-----------------"); 62 */ 63 ll mi = INF; 64 int cnt = 0; 65 ll a = 0; 66 for(i = 1; i <= n; ++i) { 67 if((a = max(d[0][i], d[1][i])) < mi) { 68 mi = a; 69 } 70 } 71 printf("Case #%d: ", k); 72 if(mi == INF) { 73 printf("Evil John\n"); 74 } 75 else { 76 int f = 0; 77 printf("%lld\n", mi); 78 for(i = 1; i <= n; ++i) { 79 a = max(d[0][i], d[1][i]); 80 if(a == mi) { 81 if(f) putchar( ); 82 printf("%d", i); 83 f = 1; 84 } 85 } 86 puts(""); 87 } 88 } 89 return 0; 90 }
2667ms

hdu 5521 Meeting(最短路)