http://acm.hdu.edu.cn/showproblem.php?pid=5521
题目意思就是给你一个图,n个城市,求 1和n相遇的最短距离,显然就是分别以1和n出发求一次最短路,答案就是 min【max( dis1[i],disn[i] )】
...但是本题给的图很特别,直接给出m个集合,每个集合里有k个点,集合内任意两点之间的边权是t。
显然不能暴力n^2建图,否则极端情况就会挂。
我们可以通过 借助一个 不存在的节点来建图:
对每个集合 new一个点n+i,联通集合内所有点的,花费为t。
这样就使得集合内所有点联通,只不过实际计算的边权为2t。没关系,我们直接在输出答案的时候把答案除二即可。
这样使得图的最大节点为 n*2,其余地方和正常最短路无异咯
跑了2S
//poj2387 --求n到1最短路 #include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <map> #include <set> #include <vector> using namespace std; struct node { int x,v; node() {} node(int a,int b) { x=a; v=b; } bool operator <(const node&b) const { return v>b.v; //***** } }; vector<node> mp[200050]; int dist1[200005]; int dist2[200005]; //n到其他点的最短路 const int inf=2147483647; priority_queue<node> qq; int st; int n,m; int main() { int t; cin>>t; void dji(int []); int cnt=1; while(t--) { int i,j; int a,b,c; cin>>n>>m; for (i=1; i<=2*n; i++) mp[i].clear(); int idx=n; for (i=1; i<=m; i++) { idx++; int tt,kk,x; scanf("%d%d",&tt,&kk); for (j=1; j<=kk; j++) { scanf("%d",&x); mp[idx].push_back(node(x,tt)); mp[x].push_back(node(idx,tt)); } } int tmpn=n; n=idx; st=1; dji(dist1); st=tmpn; dji(dist2); int minn=inf; printf("Case #%d: ",cnt++); // for (i=1;i<=tmpn;i++) dist1[i]/=2,dist2[i]/=2; for (i=1; i<=tmpn; i++) { minn=min(minn,max(dist1[i],dist2[i])); } if (dist1[tmpn]==inf) printf("Evil John\n"); else { printf("%d\n",minn/2); //实际答案除二哦 int line=0; for (i=1; i<=tmpn; i++) { if(max(dist1[i],dist2[i])==minn) { if (line) printf(" "); printf("%d",i); line=1; } } printf("\n"); } } return 0; } void dji(int dist[]) { while(!qq.empty()) qq.pop(); int i; int vis[200005]; for (i=1; i<=n; i++) { dist[i]=inf; vis[i]=0; } dist[st]=0; node sst(st,0); qq.push(sst); while(!qq.empty()) { node t=qq.top(); qq.pop(); int num=t.x; if (vis[num]) continue; vis[num]=1; for (i=0; i<mp[num].size(); i++) { node tmp=mp[num][i]; int x=tmp.x; int v=tmp.v; if (!vis[x]&&v+dist[num]<dist[x]) { dist[x]=v+dist[num]; node np(x,dist[x]); qq.push(np); } } } }