HDU 5521 Meeting
2015 ACM / ICPC 沈阳站现场赛 M题
最短路
设置N+M个节点,前N个节点是Block,后M个节点是Set,每一组Set中的点向该Set连边,从1和n开始分别求最短路。注意爆int。
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; const long long INF=1e16; const int maxn=200000+10; const int maxm=5000000+10; long long dis1[maxn],dis2[maxn],val[maxn]; bool flag1[maxn],flag2[maxn]; vector<int>G[maxn]; vector<int>Ans; struct Edge { int from; int to; }e[maxm]; int T,n,m,tot; void init() { memset(val,0,sizeof val); memset(flag1,0,sizeof flag1); for(int i=0;i<maxn;i++) dis1[i]=INF; memset(flag2,0,sizeof flag2); for(int i=0;i<maxn;i++) dis2[i]=INF; for(int i=0;i<maxn;i++) G[i].clear(); Ans.clear(); tot=0; } void AddEdge(int x,int y) { tot++; e[tot].from=x; e[tot].to=y; G[x].push_back(tot); tot++; e[tot].from=y; e[tot].to=x; G[y].push_back(tot); } void spfa1() { queue<int>Q; Q.push(1); flag1[1]=1;dis1[1]=0; while(!Q.empty()) { int h=Q.front(); Q.pop(); flag1[h]=0; for(int i=0;i<G[h].size();i++) { int id=G[h][i]; if(dis1[h]+val[e[id].to]<dis1[e[id].to]) { dis1[e[id].to]=dis1[h]+val[e[id].to]; if(flag1[e[id].to]==0) { flag1[e[id].to]=1; Q.push(e[id].to); } } } } } void spfa2() { queue<int>Q; Q.push(n); flag2[n]=1;dis2[n]=0; while(!Q.empty()) { int h=Q.front(); Q.pop(); flag2[h]=0; for(int i=0;i<G[h].size();i++) { int id=G[h][i]; if(dis2[h]+val[e[id].to]<dis2[e[id].to]) { dis2[e[id].to]=dis2[h]+val[e[id].to]; if(flag2[e[id].to]==0) { flag2[e[id].to]=1; Q.push(e[id].to); } } } } } int main() { scanf("%d",&T); for(int Case=1;Case<=T;Case++) { init(); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int s,x; long long t; scanf("%lld%d",&t,&s); val[n+i]=t; for(int j=1;j<=s;j++) { scanf("%d",&x); AddEdge(x,n+i); } } spfa1(); spfa2(); long long ans=INF; for(int i=1;i<=n;i++) { if(dis1[i]==INF||dis2[i]==INF) continue; if(max(dis1[i],dis2[i])<ans) ans=max(dis1[i],dis2[i]); } printf("Case #%d: ",Case); if(ans==INF) printf("Evil John\n"); else { printf("%lld\n",ans); for(int i=1;i<=n;i++) { if(dis1[i]==INF||dis2[i]==INF) continue; if(max(dis1[i],dis2[i])==ans) Ans.push_back(i); } for(int i=0;i<Ans.size();i++) { printf("%d",Ans[i]); if(i<Ans.size()-1) printf(" "); else printf("\n"); } } } return 0; }