http://poj.org/problem?id=3268
题目大意;有N个农厂,其中标号为x的农场要举行party,其余农场的牛要去参加,但是牛都很懒,所以不管是过去还是回来,牛都会走对于他们自己而言最短的路,要你求出所有牛中走得时间最长的一个。
思路;Dijkstra()算法变形,也可以用SPFA算法(不过这个暂时还不怎么理解),先求出到x农场的最短距离,再转置矩阵,然后求出回去的最短距离,因为这里的路是单向的 所以得求两次。最后输出最长的一个。
一直在想一种不用转置的方法,就是在引用函数的时候加入x的值,ex:void Dijkstra(int m),然后主函数调用的时候
Dijkstra(x),后来才想通是要求所有的,并不是让你去求特定的某个路径。
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
#define INF 500000
int sum[1050];
int map[1050][1050];
int dis[1050],mark[1050];
int x,n,i,j;
void d()
{
int min,k;
memset(dis,0,sizeof(dis));
memset(mark,0,sizeof(mark));
for(i=1;i<=n;i++)
{
dis[i]=map[x][i];
}
dis[x]=0;
mark[x]=1;
for(i=2;i<=n;i++)
{
min=INF;
for(j=1;j<=n;j++)
{
if(!mark[j]&&min>dis[j])
{
k=j;
min=dis[j];
}
}
mark[k]=1;
sum[k]+=min;
for(j=1;j<=n;j++)
{
if(!mark[j]&&map[k][j]+dis[k]<dis[j])
{
dis[j]=map[k][j]+dis[k];
}
}
}
}
void up()
{
int t;
for(i=1;i<=n;i++)
{
for(j=1;j<=i;j++)
{
t=map[i][j];
map[i][j]=map[j][i];
map[j][i]=t;
}
}
}
int main()
{
int m,le,max;
while(scanf("%d %d %d",&n,&m,&x)!=EOF)
{
max=0;
memset(sum,0,sizeof(sum));
memset(map,INF,sizeof(map));
while(m--)
{
scanf("%d %d %d",&i,&j,&le);
map[i][j]=le;
}
d();
up();
d();
for(i=1;i<=n;i++)
{
if(max<sum[i])
max=sum[i];
}
cout<<max<<endl;
}
return 0;
}