POJ 3268 Silver Cow Party (Dijkstra~)

http://poj.org/problem?id=3268

N只母牛(起始地点不同)要去X这个地方,给出有向图,要求求出他们到x后并且返回(不一定原路,有向图)的路程最大的母牛(算的是来回),

其中他们走到x和从x返回走的路径均是最短的。


思路:

从x到每个点的最短路径还算好求。直接Dijkstra即可

但是从每个点到x呢?

难道要n次Dijkstra?或者floyd?

不,那样效率太低了!

一个方法是进行矩阵转置,然后再来一次Dijkstra即可。

为什么这样可以?对于有向图,本来是从n个点到x的,你转置一下相当于x到n个点了。

很巧妙吧?


#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1010;
const int INF=99999;
int map[MAXN][MAXN];
int n,m,x;
void map_reverse()
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<i;j++)
			swap(map[i][j],map[j][i]);
}

void dijkstra(int dis[])
{
	bool vis[MAXN]={0};
	int cur=x;
	vis[cur]=true;
	dis[cur]=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
			if(map[cur][j]!=INF && map[cur][j] +dis[cur] < dis[j])
				dis[j]=map[cur][j] +dis[cur];

		int mini=INF;
		for(int j=1;j<=n;j++)
			if(!vis[j] && dis[j] < mini)
				mini=dis[cur=j];

		vis[cur]=true;
	}

}
int main()
{

	while(~scanf("%d%d%d",&n,&m,&x))
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
				map[i][j]=INF;
		}

		for(int i=0;i<m;i++)
		{
			int a,b,t;
			scanf("%d%d%d",&a,&b,&t);
			map[a][b]=t;
		}

		int dis1[MAXN],dis2[MAXN];
		for(int i=1;i<=n;i++)
			dis1[i]=dis2[i]=INF;

		dijkstra(dis1);
		map_reverse();
		dijkstra(dis2);

		int ans=-1;
		for(int i=1;i<=n;i++)
		{
			if(dis1[i]==INF || dis2[i]==INF)
				continue;

			int temp=dis1[i]+dis2[i];
			if(temp > ans)
				ans=temp;
		}

		printf("%d\n",ans);
	}

	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值