POJ3268,Silver Cow Party(最短路)

    这道题的大概意思就是,有n只奶牛,它们的家的编号为从1到n,编号为x的奶牛要举办party,其它奶牛都要去它家参加,参加完后又要回去,每只奶牛不论是去还是回,都会挑选最短的路径走。最终要从这些奶牛当中,算出他们各自来与回的总时长,并输出最大的那个时间。
    此题涉及的图示有向图。显然,奶牛们从x的家回到自己家的过程,可以看成是求单源最短路问题,不过,奶牛们从家里出发到x家,这个过程其实也可以看成是从x家回到自己家,即同样转化为单源最短路问题,**只需要把从i到j的边的权与从j到i的边的权交换一下就好了。**

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define inf 10000005
using namespace std;
const int maxn=1e3+5;
int map[maxn][maxn],dis_to[maxn],dis_back[maxn];	//用邻接矩阵好写一点。
bool vis[maxn];

void dijkstra(int n,int s)
{
	for(int i=1;i<=n;i++)
	{
		dis_back[i]=map[s][i];
		vis[i]=0;
	}
	vis[s]=1;
	for(int i=1;i<=n;i++)
	{
		int temp=inf,k;
		for(int j=1;j<=n;j++)
			if(!vis[j]&&temp>dis_back[j])
				temp=dis_back[k=j];
		if(temp==inf)	break;
		vis[k]=1;
		for(int j=1;j<=n;j++)
			dis_back[j]=min(dis_back[j],dis_back[k]+map[k][j]);
	}
	for(int i=1;i<=n;i++)
		for(int j=i;j<=n;j++)
			swap(map[i][j],map[j][i]);
	for(int i=1;i<=n;i++)
	{
		dis_to[i]=map[s][i];
		vis[i]=0;
	}
	vis[s]=1;
	for(int i=1;i<=n;i++)
	{
		int temp=inf,k;
		for(int j=1;j<=n;j++)
			if(!vis[j]&&temp>dis_to[j])
				temp=dis_to[k=j];
		if(temp==inf)	break;
		vis[k]=1;
		for(int j=1;j<=n;j++)
			dis_to[j]=min(dis_to[j],dis_to[k]+map[k][j]);
	}
}

int main()
{
	int n,x,m;
	scanf("%d%d%d",&n,&m,&x);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(i!=j)	map[i][j]=inf;
			else map[i][j]=0;
	for(int i=1;i<=m;i++)
	{
		int u,v,t;
		scanf("%d%d%d",&u,&v,&t);
		map[u][v]=t;
	}
	dijkstra(n,x);
	int ans=0;
	for(int i=1;i<=n;i++)
		ans=max(ans,dis_to[i]+dis_back[i]);
	printf("%d\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值