标签:
1 /** 2 题意:有n个点,m个集合 3 集合内的点 两两 到的时间为 ti; 4 有两个人 在1,n; 输出最小相遇时间,以及哪些点(可以走走停停); 5 6 思路:****将集合抽象为点。访问过的集合不再访问。 7 Set集合抽象的点。 8 Belong属于哪个集合。 9 */ 10 #include<bits/stdc++.h> 11 using namespace std; 12 typedef long long ll; 13 const ll INF = 0x7f7f7f7f; 14 typedef pair<int,int> P;// first是最短距离,second是顶点编号 15 struct edge{ 16 int to; 17 int cost; 18 }; 19 vector<edge> G[100005]; 20 ll d1[100005],d2[100005],t[100005]; 21 int setsize[100005]; 22 bool vis[100005]; 23 bool visset[100005]; 24 int V,E,n,m; 25 vector<int> Belong[100005]; 26 vector<int> Set[100005]; 27 void dijkstra(int s,ll *d){ 28 priority_queue<P,vector<P>,greater<P> > que; 29 for(int i = 1 ; i <= n ; i ++) d[i] = INF; 30 memset(vis,false,sizeof(vis)); 31 memset(visset,false,sizeof(visset)); 32 d[s] = 0; 33 que.push(P(0,s)); 34 while(!que.empty()){ 35 P p = que.top(); que.pop(); 36 int u = p.second; 37 // if(d[u] < p.first) continue; 38 if(vis[u]) continue; 39 vis[u] = true; 40 /* 41 for(int i = 0 ; i < G[u].size() ; i ++){ 42 edge& e = G[u][i]; 43 if(d[e.to] > d[u] + e.cost){ 44 d[e.to] = d[u] + e.cost; 45 que.push(P(d[e.to],e.to)); 46 } 47 } 48 */ 49 for(int i = 0 ; i < Belong[u].size() ; i ++){ // u 属于哪些集合 50 int st = Belong[u][i]; 51 if(visset[st]) continue; 52 visset[st] = true; 53 for(int j = 0 ; j < setsize[st] ; j ++){ 54 int v = Set[st][j]; 55 if(u == v) continue; 56 if(d[v] > d[u] + t[st]){ 57 d[v] = d[u] + t[st]; 58 que.push(P(d[v],v)); 59 } 60 } 61 } 62 } 63 } 64 65 void init(){ 66 scanf("%d%d",&n,&m); 67 for(int i = 0 ; i <= n ; i ++) Belong[i].clear(); 68 for(int i = 0 ; i <= m ; i ++) Set[i].clear(); 69 for(int i = 0 ; i < m ; i ++){ 70 scanf("%lld%d",&t[i],&setsize[i]); 71 for(int j = 0 ; j < setsize[i] ; j ++){ 72 int tmp; 73 scanf("%d",&tmp); 74 Set[i].push_back(tmp); //集合内的点。 75 Belong[tmp].push_back(i); //属于哪些集合。 76 } 77 } 78 } 79 void solve(int kase){ 80 dijkstra(1,d1); 81 dijkstra(n,d2); 82 ll ans = 0x7f7f7f7f; 83 for(int i = 1 ; i <= n ; i ++){ 84 ans = min(ans,max(d1[i],d2[i])); 85 } 86 if(ans == 0x7f7f7f7f) printf("Case #%d: Evil John\n",kase); 87 else{ 88 printf("Case #%d: %d\n",kase,ans); 89 bool f = false; 90 for(int i = 1 ; i <= n ; i ++){ 91 if(ans == max(d1[i],d2[i])){ 92 if(f) printf(" "); 93 printf("%d",i); 94 f = true; 95 } 96 } 97 printf("\n"); 98 } 99 100 101 } 102 103 int main(){ 104 int T; 105 scanf("%d",&T); 106 for(int i = 1 ; i <= T ; i ++){ 107 init(); 108 solve(i); 109 } 110 return 0; 111 }
HDU 5521 Meeting(好题,最短路,2015ACM/ICPC亚洲区沈阳站)
标签:
原文地址:http://www.cnblogs.com/zstu-jack/p/5436164.html