HDU 5521 Meeting (最短路)

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

题意:

        有一个n个点的图,会给你m个集合,每个集合内的点,距离都是t[i]

        然后A在点1,B在点n,然后让你找到一个点,使得max(disA[i],disB[i])最小

        如果有多个答案,按照字典序输出所有答案

        如果没有答案输出Evil John

思路:

        两次dijkstra,注意不能直接建边。对于当前点所在的集合,要是之前没有遍历过,就遍历集合内所有的点,更新d[i]。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <queue>
  5 #include <map>
  6 using namespace std;
  7 typedef __int64 LL;
  8 typedef pair <LL, int> P;
  9 const int N = 1e5 + 5;
 10 LL d1[N], d2[N], inf = 1e16;
 11 int a[N];
 12 vector <int> G[N], belong[N];
 13 bool vis[N];
 14 void dij(int s, int n) {
 15     for(int i = 1; i <= n; ++i) {
 16         d1[i] = inf;
 17         vis[i] = false;
 18     }
 19     d1[s] = 0;
 20     priority_queue <P, vector<P>, greater<P> > que;
 21     while(!que.empty()) {
 22         que.pop();
 23     }
 24     que.push(make_pair(d1[s], s));
 25     while(!que.empty()) {
 26         P temp = que.top();
 27         int u = temp.second;
 28         que.pop();
 29         if(d1[u] < temp.first)
 30             continue;
 31         for(int i = 0; i < belong[u].size(); ++i) {
 32             int x = belong[u][i];
 33             if(vis[x]) //集合之前遍历过
 34                 continue;
 35             vis[x] = true;
 36             for(int j = 0; j < G[x].size(); ++j) {
 37                 int v = G[x][j];
 38                 if(v != u && d1[v] > d1[u] + a[x]) {
 39                     d1[v] = d1[u] + a[x];
 40                     que.push(make_pair(d1[v], v));
 41                 }
 42             }
 43         }
 44     }
 45 }
 46 void dij2(int s, int n) {
 47     for(int i = 1; i <= n; ++i) {
 48         d2[i] = inf;
 49         vis[i] = false;
 50     }
 51     d2[s] = 0;
 52     priority_queue <P, vector<P>, greater<P> > que;
 53     while(!que.empty()) {
 54         que.pop();
 55     }
 56     que.push(make_pair(d2[s], s));
 57     while(!que.empty()) {
 58         P temp = que.top();
 59         int u = temp.second;
 60         que.pop();
 61         if(d2[u] < temp.first)
 62             continue;
 63         for(int i = 0; i < belong[u].size(); ++i) {
 64             int x = belong[u][i];
 65             if(vis[x]) //集合之前遍历过
 66                 continue;
 67             vis[x] = true;
 68             for(int j = 0; j < G[x].size(); ++j) {
 69                 int v = G[x][j];
 70                 if(v != u && d2[v] > d2[u] + a[x]) {
 71                     d2[v] = d2[u] + a[x];
 72                     que.push(make_pair(d2[v], v));
 73                 }
 74             }
 75         }
 76     }
 77 }
 78 void init(int n) {
 79     for(int i = 1; i <= n; ++i) {
 80         G[i].clear();
 81         belong[i].clear();
 82     }
 83 }
 84 vector <int> res;
 85 int main()
 86 {
 87     int t, n, m;
 88     scanf("%d", &t);
 89     for(int ca = 1; ca <= t; ++ca) {
 90         scanf("%d %d", &n, &m);
 91         init(n);
 92         res.clear();
 93         int num, x;
 94         for(int k = 1; k <= m; ++k) {
 95             scanf("%d %d", &a[k], &num);
 96             for(int i = 1; i <= num; ++i) {
 97                 scanf("%d", &x);
 98                 G[k].push_back(x); //集合k内的点
 99                 belong[x].push_back(k); //点x所在的集合
100             }
101         }
102         dij(1, n);
103         dij2(n, n);
104         LL ans = inf;
105         for(int i = 1; i <= n; ++i) {
106             ans = min(ans, max(d1[i], d2[i]));
107         }
108         printf("Case #%d: ", ca);
109         if(ans == inf) {
110             printf("Evil John\n");
111         } else {
112             for(int i = 1; i <= n; ++i) {
113                 if(d1[i] <= ans && d2[i] <= ans) {
114                     res.push_back(i);
115                 }
116             }
117             int xx = res.size();
118             printf("%I64d\n", ans);
119             for(int i = 0; i < xx - 1; ++i) {
120                 printf("%d ", res[i]);
121             }
122             printf("%d\n", res[xx - 1]);
123         }
124     }
125     return 0;
126 }

 

posted @ 2016-10-14 22:07  Recoder  阅读(237)  评论(0编辑  收藏  举报