71.双向最短路径:聚会
2016-03-13 05:53
225 查看
1992 聚会[/b]
时间限制: 1s
空间限制:
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;
}
相关文章推荐
- 71.双向最短路径:聚会
- [leetcode] 245. Shortest Word Distance III 解题报告
- bzoj 1433: [ZJOI2009]假期的宿舍
- bzoj 1432: [ZJOI2009]Function
- bzoj 1415: [Noi2005]聪聪和可可
- bzoj 1412: [ZJOI2009]狼和羊的故事
- Palindrome 系列
- 谷歌人机大战与新时代的来临
- 工厂模式之小结与区别(6)
- 抽象工厂模式(5)
- 抽象工厂模式(4)
- leetcode@ [116/117] Populating Next Right Pointers in Each Node I & II (Tree, BFS)
- !getApplicationContext()和Activity.this区别
- 【Android】20.4 录音
- MarkDown的简介
- 【Android】20.3 拍照和视频录制
- python中一些常用的module小结
- Jquery Ajax 跨域之JSONP方式极简示例,服务端是.net的ashx
- [leetcode] 311. Sparse Matrix Multiplication 解题报告
- C++ Exceptinal 类之间的关系