公牛排队 dijkstra反向建边

One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.

Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.

Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?

Input
Line 1: Three space-separated integers, respectively: N, M, and X
Lines 2… M+1: Line i+1 describes road i with three space-separated integers: Ai, Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.
Output
Line 1: One integer: the maximum of time any one cow must walk.
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

Hint
Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.

解题报告:这里就要用到反向建边的思想,先找到所有点到起点的距离,然后把起点到所有点的距离反一下,再用一次dijkstra,两个数组值之和就是来回距离了。

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
const	int N=1010;
int g[N][N];
int n,m,x;
int d[N];
int back[N];
bool st[N];
void dijkstra()
{
   
	memset(d,0x3f,sizeof d);
	memset(st,0,sizeof st);
	d[x]=0;
	for(int i=0;i<n;i++)
	{
   
		int t=-1;
		for(int j=1;j<=n;j++)
		if(!st[j]&&(t==-1||d[j]<d[t]))
		t=j;
	// cout<<t<<endl;
		st[t]=1;
		for(int j=1;j<=n;j++)
		d[j]=min(d[j],d[t]+g[t][j]);
	}
}
int main()
{
   
	scanf("%d%d%d",&n,&m,&x);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	if(i==j)	g[i][j]=0;
	else g[i][j]=0x3f3f3f3f;
	while(m--)
	{
   
		int a,b,c;
		scanf("%d%d%d",&a,&b,&c);
		g[a][b]=min(g[a][b],c);
	}
	dijkstra();
	memcpy(back,d,sizeof back);
	for(int i=1;i<n;i++)
	 for(int j=i+1;j<=n;j++)
	swap(g[i][j],g[j][i]);
	dijkstra();
	for(int i=1;i<=n;i++)
	back[i]+=d[i];
	int ans=0;
	for(int i=1;i<=n;i++)
	ans=max(back[i],ans);
	printf("%d\n",ans);
	return 0;
}
全部评论

相关推荐

门口唉提是地铁杀:之前b站被一个游戏demo深深的吸引了。看up主页发现是个初创公司,而且还在招人,也是一天60。二面的时候要我做一个登录验证和传输文件两个微服务,做完要我推到github仓库,还要我加上jaeger和一堆运维工具做性能测试并且面试的时候投屏演示。我傻乎乎的做完以后人家跟我说一句现在暂时不招人,1分钱没拿到全是白干
你的秋招第一场笔试是哪家
点赞 评论 收藏
分享
06-02 15:53
阳光学院 Java
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-01 11:27
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务