您的位置:首页 > 其它

HDU 5521 Meeting

2015-11-04 08:50 330 查看
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
=1;dis2
=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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: