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);
}
}
}
}