POJ3268 Silver Cow Party,SPFA+转置矩阵

看到题目的数据量,就知道要用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 : [email protected]
 * 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 
#include 
#include 
#include 
#include 
#include 

#define MAX 1100
#define maxint 1<<30

using namespace std;

int farm1[MAX][MAX],farm2[MAX][MAX],path1[MAX],path2[MAX],visit[MAX];
queue 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;ilen)
				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]


你可能感兴趣的:(POJ,最短路径)