hdu 5521 Meeting(最短路)
题目链接:hdu 5521 Meeting
题意:
有n个点,m个集合,每个集合之间的点到达的时间是相同的。
问一个人从1出发,一个人从n出发,他们相遇的最小时间是多久。
题解:
对于第i个集合,新设立一个点n+i,然后addedge(n+i,x,time),addedge(x,n+i,time)
然后就可以求出从1出发和从n出发到任意点的最短路了。
然后取一下两个最短路最大值的最小就行了。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=(a);i<=(b);++i) 3 using namespace std; 4 typedef long long ll; 5 6 const int N=2e6+7; 7 ll inf=1ll<<62; 8 int v[N*2],w[N*2],nxt[N*2],g[N],ed,n; 9 ll d[N],d2[N]; 10 void adg(int x, int y, int z) { v[++ed] = y; w[ed] = z; nxt[ed] = g[x]; g[x] = ed;} 11 typedef pair<ll, int>P; 12 priority_queue<P, vector<P>, greater<P> > Q; 13 void dijkstra(int S,ll *d) { 14 int i, x; 15 for (i = 1; i <= n; i++)d[i] = inf; Q.push(P(d[S] = 0, S)); 16 while (!Q.empty()) { 17 P t = Q.top(); Q.pop(); 18 if (d[x = t.second] < t.first)continue; 19 for (i = g[x]; i; i = nxt[i])if (d[x] + w[i] < d[v[i]]) 20 Q.push(P(d[v[i]] = d[x] + w[i], v[i])); 21 } 22 } 23 24 int t,cas,nn,mm; 25 vector<int>V; 26 27 int main(){ 28 scanf("%d",&t); 29 while(t--) 30 { 31 scanf("%d%d",&nn,&mm); 32 n=nn+mm; 33 F(i,1,n)g[i]=0;ed=0; 34 F(i,1,mm) 35 { 36 int num,time,x; 37 scanf("%d%d",&time,&num); 38 F(j,1,num) 39 { 40 scanf("%d",&x); 41 adg(x,nn+i,0); 42 adg(nn+i,x,time); 43 } 44 } 45 dijkstra(1,d),dijkstra(nn,d2); 46 ll ans=inf; 47 F(i,1,nn) 48 { 49 ll now=max(d[i],d2[i]); 50 if(now==inf)continue; 51 if(ans>now) 52 { 53 ans=now; 54 V.clear(); 55 V.push_back(i); 56 }else if(ans==now)V.push_back(i); 57 } 58 if(ans==inf)printf("Case #%d: Evil John\n",++cas); 59 else 60 { 61 printf("Case #%d: %lld\n",++cas,ans); 62 int first=1; 63 for(auto it:V) 64 { 65 if(first)printf("%d",it),first=0; 66 else printf(" %d",it); 67 } 68 puts(""); 69 } 70 } 71 return 0; 72 }