HDU 5521 Meeting 最短路
Meeting
Time Limit: 20 Sec
Memory Limit: 256 MB
题目连接
http://acm.hdu.edu.cn/showproblem.php?pid=5521
Description
fences they were separated into different blocks. John's farm are divided into $n$ blocks labelled from $1$ to $n$.
Bessie lives in the first block while Elsie lives in the $n$-th one. They have a map of the farm
which shows that it takes they $t_i$ minutes to travel from a block in $E_i$ to another block
in $E_i$ where $E_i~(1\le i\le m)$ is a set of blocks. They want to know how soon they can meet each other
and which block should be chosen to have the meeting.
Input
The first line contains an integer T (1≤T≤6), the number of test cases. Then T test cases
follow.
The first line of input contains n and m. 2≤n≤105. The following m lines describe the sets Ei (1≤i≤m). Each line will contain two integers ti(1≤ti≤109) and Si (Si>0) firstly. Then Si integer follows which are the labels of blocks in Ei. It is guaranteed that ∑mi=1Si≤106.
Output
For each test case, if they cannot have the meeting, then output "Evil John" (without quotes) in one line.
Otherwise, output two lines. The first line contains an integer, the time it takes for they to meet.
The second line contains the numbers of blocks where they meet. If there are multiple
optional blocks, output all of them in ascending order.
Sample Input
5 4
1 3 1 2 3
2 2 3 4
10 2 1 5
3 3 3 4 5
3 1
1 2 1 2
Sample Output
Case #1: 3
3 4
Case #2: Evil John
HINT
题意
有一个n个点的图,会给你m个集合,每个集合内的点,距离都是t[i]
然后A在点1,B在点n,然后让你找到一个点,使得max(disA[i],disB[i])最小
如果有多个答案,按照字典序输出所有答案
如果没有答案输出Evil John
题解:
dij,对于每个集合,我们只会松弛一次
因为我们都是从最短的跑过去的
所以直接这样暴力跑就好了
代码
#include<iostream> #include<stdio.h> #include<cstring> #include<queue> using namespace std; #define maxn 100500 const int inf=0x3f3f3f3f; const long long infll = 0x3f3f3f3f3f3f3f3fLL; vector<int> G[maxn],E[maxn]; int n,m; long long t[maxn]; long long d1[maxn]; long long d2[maxn]; int vis[maxn],flag[maxn]; struct node { long long x; int y; friend bool operator < (const node & a,const node & b) { return a.x>b.x; } }; void dij(int st, long long dis[]) { priority_queue<node> Q; for (int i = 1; i <= n; i++) dis[i] = infll; dis[st] = 0; memset(vis, 0, sizeof(vis)); memset(flag, 0, sizeof(flag)); node ttt;ttt.x = 0,ttt.y = st; Q.push(ttt); while (!Q.empty()) { node x = Q.top(); Q.pop(); int u = x.y; if (vis[u]) continue; vis[u] = 1; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i]; if (flag[v]) continue; flag[v] = true; for (int j = 0; j < E[v].size(); j++) { int vv = E[v][j]; if (vv == u) continue; if (dis[vv] > dis[u] + t[v]) { dis[vv] = dis[u] + t[v]; ttt.x = dis[vv];ttt.y = vv; Q.push(ttt); } } } } } int main() { int T;scanf("%d",&T); for(int cas=1;cas<=T;cas++) { scanf("%d%d",&n,&m); for(int i=0;i<maxn;i++) G[i].clear(); for(int i=0;i<maxn;i++) E[i].clear(); memset(t,0,sizeof(t)); for(int i=1;i<=m;i++) { int num; scanf("%lld%d",&t[i],&num); for(int j=1;j<=num;j++) { int x;scanf("%d",&x); G[x].push_back(i); E[i].push_back(x); } } dij(n,d2); dij(1,d1); long long ans = infll; for(int i=1;i<=n;i++) { if(ans>max(d1[i],d2[i])) ans = max(d1[i],d2[i]); } if(ans == infll) { printf("Case #%d: Evil John\n",cas); continue; } vector<int> Ans; for(int i=1;i<=n;i++) { if(max(d1[i],d2[i])==ans) Ans.push_back(i); } printf("Case #%d: %lld\n",cas,ans); int first = 0; for(int i=0;i<Ans.size();i++) { if(first==0) { printf("%d",Ans[i]); first = 1; } else printf(" %d",Ans[i]); } printf("\n"); } }