题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long LL;
#define N 1000005
#define M 2000005
const LL inf = 1e17;
struct node
{
int v, nxt;
LL w;
} edge[M];
struct nd
{
int p;
LL d;
nd() {}
nd(LL _d, int _to):d(_d), p(_to) {}
bool operator < (const nd &a) const
{
return d > a.d;
}
};
int tot, n, m, nn, used[N], head[N];
LL da[N], db[N];
void add(int u, int v, LL w)
{
edge[tot].v = v;
edge[tot].w = w;
edge[tot].nxt = head[u];
head[u] = tot++;
}
void Dijkstra(int s, LL d[])
{
priority_queue<nd> que;
while(!que.empty()) que.pop();
for(int i = 0 ; i <= nn; i++) d[i] = inf;
memset(used, 0, sizeof(used));
d[s] = 0;
que.push(nd(d[s], s));
while(!que.empty())
{
nd top = que.top();
que.pop();
int u = top.p;
if(used[u]) continue;
used[u] = 1;
for(int k = head[u]; ~k; k = edge[k].nxt)
{
int v = edge[k].v;
int w = edge[k].w;
if(d[u]+w < d[v])
{
d[v] = d[u] + w;
que.push(nd(d[v], v));
}
}
}
}
int main()
{
int t;
scanf("%d", &t);
for(int cas = 1; cas <= t; cas++)
{
scanf("%d%d", &n, &m);
memset(head, -1, sizeof(head));
tot = 0;
nn = n;
for(int i = 0; i < m; i++)
{
LL dis;
int num, a;
nn++;
scanf("%I64d%d", &dis, &num);
for(int j = 0; j < num; j++)
{
scanf("%d", &a);
add(a, nn, dis);
add(nn, a, dis);
}
}
Dijkstra(1, da);
Dijkstra(n, db);
LL ans = inf;
for(int i = 1; i <= n; i++)
ans = min(ans, max(da[i], db[i]));
printf("Case #%d: ", cas);
if(ans==inf) printf("Evil John\n");
else
{
printf("%I64d\n", ans/2);
bool f = 0;
for(int i = 1; i <= n; i++)
{
if(max(da[i], db[i]) == ans)
{
if(f) printf(" ");
f = 1;
printf("%d", i);
}
}
puts("");
}
}
return 0;
}