您的位置:首页 > 其它

71.双向最短路径:聚会

2016-03-13 05:53 225 查看


1992 聚会[/b]

时间限制: 1
s

空间限制:
128000 KB

题目等级 :
黄金 Gold

题解

题目描述 Description

小S
想要从某地出发去同学k的家中参加一个party,但要有去有回。他想让所用的

时间尽量的短。但他又想知道从不同的点出发,来回的最短时间中最长的时间是多

少,这个任务就交给了你

输入描述 Input
Description

第一行三个正整数n,
m, k(n是节点个数,m是有向边的条数,k是参加聚会的地点

编号)( 1 ≤ n ≤ 1000 ,1 ≤ m ≤ 100,000)

第二行..m + 1行每行3个整数x,y,w 代表从x到y需要花w的时间 0

输出描述 Output
Description

输出从不同的节点出发的最短时间中最长的时间

样例输入 Sample
Input

4 8
2

1 2 4

1 3 2

1 4 7

2 1 1

2 3 5

3 1 2

3 4 4

4 2 3

样例输出 Sample
Output

10

数据范围及提示 Data Size &
Hint


分类标签 Tags 点此展开

最短路 图论

思路:跑两边地杰斯特拉,一次正着跑,一次倒跑(把所有的边都反向存起来)
代码:

#include

using namespace std;

#include

#include

struct Edge{

int
u,v,w,next;

};

#include

Edge
edge[100001<<1],edge1[100001<<1];//注意边表一定要开到n*n的大小,才可以不越界

const int INF=0x7fffffff;
// 赋值最大值,0x7(再加上七个f)就是无限数,这个题虽然w《=100,但是边的数目很多时,仍会超过999999,所以要赋这个数

int
head[100001],visit[100001],head1[100001],visit1[100001];

int dis[100001],dis1[100001],dis2[100001];

int n,m,k;

void input()

{

scanf("%d%d%d",&n,&m,&k);///n
ge dian

for(int
i=1;i<=n;++i)

{

dis[i]=INF;

dis1[i]=INF;

}

int
t=0;

for(int
i=1;i<=n;++i)

for(int
j=1;j<=n;++j)

{

edge[++t].w=INF;

edge1[t].w=INF;

}

for(int
i=1;i<=m;++i)

{

scanf("%d%d%d",&edge[i].v,&edge[i].u,&edge[i].w);

edge[i].next=head[edge[i].u];

if(edge[i].u==k)

dis[edge[i].v]=edge[i].w;

head[edge[i].u]=i;

edge1[i].u=edge[i].v;

edge1[i].v=edge[i].u;

edge1[i].w=edge[i].w;

edge1[i].next=head1[edge1[i].u];

head1[edge1[i].u]=i;

if(edge1[i].u==k)

dis1[edge1[i].v]=edge1[i].w;

}

}

void dijstra()

{

dis[k]=0;

visit[k]=1;

for(int
i=1;i<=n-1;i++)

{

int
p=0,min1=INF;

for(int
j=1;j<=n;++j)

{

if(!visit[j]&&dis[j]

{

p=j;

min1=dis[j];

}

}

if(p==0)
break;

visit[p]=1;

for(int
l=head[p];l!=0;l=edge[l].next)

{

if(!visit[edge[l].v]&&edge[l].w+dis[edge[l].u]

{

dis[edge[l].v]=edge[l].w+dis[edge[l].u];

}

}

}

}

void dijstra1()

{

dis1[k]=0;

visit1[k]=1;

for(int
i=1;i<=n-1;i++)

{

int
p=0,min1=INF;

for(int
j=1;j<=n;++j)

{

if(!visit1[j]&&dis1[j]

{

p=j;

min1=dis1[j];

}

}

if(p==0)
break;

visit1[p]=1;

for(int
l=head1[p];l!=0;l=edge1[l].next)

{

if(!visit1[edge1[l].v]&&edge1[l].w+dis1[edge1[l].u]

{

dis1[edge1[l].v]=edge1[l].w+dis1[edge1[l].u];

}

}

}

}

int main()

{

input();

dijstra();

dijstra1();

for(int
i=1;i<=n;++i)

dis2[i]=dis[i]+dis1[i];

sort(dis2+1,dis2+n+1);

printf("%d",dis2
);

return
0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: