您的位置:首页 > 其它

hdu5521Meeting(dijkstra最短路)icpc沈阳赛区M题

2015-11-04 20:07 519 查看
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5521
题目大意:

t组数据,每组数据 n 个点,m 个条件,每个条件告诉你有 k 个点,他们两两的距离都是 d。

有两个人,一个从 1 出发,一个从 n 出发,在这n 个点相遇的最短时间是多少。

思路:

这题主要是数据量太大了,如果给你多个点,两两建边的话,就会爆内存了。(如图是五个点所建的边)



所以我新建了两个点,把所有点和这两个点连接,这样就行了。

然后再来一发dijkstra算法就好了。



AC代码:(我的代码写的有点乱,建议参考一下用自己的方法写)

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
#define     ll __int64
const int Ni=100010;
const int N=1e5+2e6+10;
const int INF=1<<27;
int num[Ni];
struct node{
int to;
ll cost;
node(int a,ll b){to=a;cost=b;}
bool operator<(const node &a) const
{
if(cost==a.cost) return to<a.to;
else return cost>a.cost;
}
};
vector<node>eg
;
ll dist1
,dist2
;
int n,m;
void dijkstra(int s,ll *dis)
{
int i;
for(i=0;i<=m*2+n+1;i++) dis[i]=INF;
dis[s]=0;
priority_queue<node> q;
q.push(node(s,0));
while(!q.empty())
{
node x=q.top();
q.pop();
for(i=0;i<eg[x.to].size();i++)
{
node y=eg[x.to][i];
if(dis[y.to]>x.cost+y.cost)
{
dis[y.to]=x.cost+y.cost;
q.push(node(y.to,dis[y.to]));
}
}
}
}
int main()
{
int a,b,d,k;

int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=2*n+2*m+1;i++) eg[i].clear();
for(int i=1;i<=m;i++)
{
scanf("%d%d",&d,&k);
int in=i+n;
int out=i+m+n;
int x;
eg[in].push_back(node(out,d));
for(int j = 1;j <= k ;j++)
{
scanf("%d",&x);
eg[out].push_back(node(x,0));
eg[x].push_back(node(in,0));
}

}

ll sum;
ll maxans = INF;
int flag=0;
dijkstra(1,dist1);
dijkstra(n,dist2);
for(int i=1;i<=n;i++)
maxans=min(maxans,max(dist1[i],dist2[i]));

printf("Case #%d: ",cas);
if(maxans==INF)
{
printf("Evil John\n");
}
else
{
printf("%I64d\n", maxans);
for(int i=1;i<=n;i++)
{
if(maxans==max(dist1[i],dist2[i])){
if(flag==1) printf(" ");
printf("%d",i);
flag=1;
}
}
printf("\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu