POJ3268 Silver Cow Party,SPFA+转置矩阵

本文介绍如何使用SPFA算法解决特定图论问题,特别是在求解最短路径时的应用。通过两个矩阵farm1和farm2来分别表示正常距离和装置转换后的距离,并通过SPFA算法计算从特定节点出发到其它所有节点的最短往返距离。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看到题目的数据量,就知道要用SPFA了。问题在于是否要对每个顶点求SPFA呢?事实上不是的。如果用farm表示正常的距离矩阵,transform表示farm装置后的矩阵。对farm求x的SPFA可以得出x到各个顶点的最短距离,也就是返回时的最短距离,那各个顶点到到x的最短距离呢?因为transform是farm的转置矩阵,即farm[a][b]=transform[b][a]=len,可以知道在transform中每条边的方向相反了,长度不变,这时对transform的x求SPFA,就可以得到各个顶点到X的最短距离了。如果仍有疑问的同学可以自己画图演示一下。


/*******************************************************************************
 * Author : Neo Fung
 * Email : neosfung@gmail.com
 * Last modified : 2011-09-14 22:03
 * Filename : POJ3268 Silver Cow Party.cpp
 * Description : 
 * *****************************************************************************/
// POJ3268 Silver Cow Party.cpp : Defines the entry point for the console application.
//

// #include "stdafx.h"
// #define DEBUG

#include <fstream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <memory.h>
#include <queue>

#define MAX 1100
#define maxint 1<<30

using namespace std;

int farm1[MAX][MAX],farm2[MAX][MAX],path1[MAX],path2[MAX],visit[MAX];
queue<int> myqueue;

void fspa(int (*farm)[MAX],int source,int n,int *path)
{
	for(int i=1;i<=n;++i)
		path[i]=maxint,visit[i]=0;
	path[source]=0;
	visit[source]=1;
	myqueue.push(source);

	while(!myqueue.empty())
	{
		int temp=myqueue.front();
		myqueue.pop();
		visit[temp]=0;
		for(int i=1;i<=n;++i)
			if(path[i]-path[temp]>farm[temp][i])
			{
				path[i]=path[temp]+farm[temp][i];
				if(!visit[i])
					myqueue.push(i),visit[i]=1;
			}
	}
}

int main(void)
{
#ifdef DEBUG  
	freopen("data.txt","r",stdin);  
#endif  

	int n,m,x,a,b,len;

	while(scanf("%d %d %d",&n,&m,&x)!=EOF)
	{
		for(int i=1;i<=n;++i)
		{
			for(int j=i+1;j<=n;++j)
				farm1[i][j]=farm1[j][i]=farm2[i][j]=farm2[j][i]=maxint;
			farm1[i][i]=farm2[i][i]=0;
		}
		for(int i=0;i<m;++i)
		{
			scanf("%d %d %d",&a,&b,&len);
			if(farm1[a][b]>len)
				farm1[a][b]=farm2[b][a]=len;
		}
		
		fspa(farm1,x,n,path1);
		fspa(farm2,x,n,path2);

		int maxlen=0;
		for(int i=1;i<=n;++i)
			if(maxlen-path1[i]<path2[i])
				maxlen=path1[i]+path2[i];
		printf("%d\n",maxlen);
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值