HPU 1413: StarFarming [最短路]

题目描述

星农(StarFarming)公司计划要给员工发路费津贴,发放的规则是这样的:1n-1代表各个员工家的序号,n代表公司。路费津贴只发给上班的最短路与回家的最短路的总路程最长的人。该市的路建造的有些奇怪,修路只修单行道,即只允许往某一个方向通行。

现在给你城市的有向图的地图,TLG请你帮忙计算谁能得到津贴,以及他上班和回家的总路程是多少。

输入

有多组测试数据。

每组第一行输入两个整数NM。表示点的个数,与单行道的数量(可能有重复)

接下来m行,每行输入三个整数x,y,z。表示从xy城市有一条单行道,距离为z

题目保证至少一人存在来回的路径。不存在的不发津贴(班都没法好好上还想要钱?!)

1N1000

1M100000

1x,yN

1z200

输出

对于每组数据,输出两个整数,分别表示获得津贴的人的序号以及总路程。(如果有多个人路程相同,取序号最小的)

样例输入

4 7
1 2 2
2 3 2
1 3 4
4 1 2
4 2 2
3 4 1
4 3 5

样例输出

1 7

提示

对于样例,

1来回需要的最短路程是71->2->3->4->1

2来回需要的最短路程是52->3->4->2

3来回需要的最短路程是53->4->2->3

所以输出1 7


解题思路:暑假做过这道题,当时没做出来,当时写的应该是先找到公司到员工家的最短路,然后分别从各个员工价出发计算到公司的最短路,但是如果调用n次Dijkstra肯定超时,但是没想到什么办法解决。现在看下其实从各个员工到公司的最短路只需调用再一次Dijkstra,这道题是单向路,只需要把每条路的起点终点调换一下位置,然后算出的就从公司到各个员工家的最短路转换成了各个员工到公司的最短路。

代码:

#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f
#define N 1010
#define M 100010
int map[N][N],mapp[N][N]; 
int n,m;
int d[N];
int book[N];
void Dijkstra()
{
	int i,j;
	memset(book,0,sizeof(book));
	book[n]=1;
	for(i=1;i<=n;i++)
	{
		d[i]=map[n][i];
	}
	d[n]=0;
//	for(i=1;i<=n;i++)
//	{
//		printf("%d ",d[i]);
//	}
//	printf("\n");
//	printf("%d %d\n",d[n],book[n]);
	for(i=1;i<=n;i++)
	{
		int min_cost = INF;
		int index=-1;
		for(j=1;j<=n;j++)
		{
			if(d[j]<min_cost&&book[j]==0)
			{
				min_cost=d[j];
				index=j;
			}
		}
		//printf("index=%d\n",index);
		if(index==-1)
			break;
	
		book[index]=1;
		for(j=1;j<=n;j++)
		{
			if(book[j]==0&&d[j]>min_cost+map[index][j])
			{
				d[j]=min_cost+map[index][j];
			}
		}
	}
//	for(i=1;i<=n;i++)
//	{
//		printf("%d ",d[i]);
//	}
//	printf("\n");
}
int book1[N];
int d1[N];
void Dijkstra1()
{
	int i,j;
	memset(book1,0,sizeof(book1));
	book1[n]=1;
	for(i=1;i<=n;i++)
	{
		d1[i]=mapp[n][i];
	}
	d1[n]=0;
//	for(i=1;i<=n;i++)
//	{
//		printf("%d ",d1[i]);
//	}
//	printf("\n");
//	printf("%d %d\n",d1[n],book1[n]);
	for(i=1;i<=n;i++)
	{
		int min_cost = INF;
		int index=-1;
		for(j=1;j<=n;j++)
		{
			if(d1[j]<min_cost&&book1[j]==0)
			{
				min_cost=d1[j];
				index=j;
			}
		}
	//	printf("index=%d\n",index);
		if(index==-1)
			break;
	
		book1[index]=1;
		for(j=1;j<=n;j++)
		{
			if(book1[j]==0&&d1[j]>min_cost+mapp[index][j])
			{
				d1[j]=min_cost+mapp[index][j];
			}
		}
	}
//	for(i=1;i<=n;i++)
//	{
//		printf("%d ",d1[i]);
//	}
//	printf("\n");
}
int main()
{
	int i,j,k,l,u,v,w;
	int a[N];
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(map,INF,sizeof(map));
		memset(mapp,INF,sizeof(mapp));
		memset(a,0,sizeof(a));
		for(i=1;i<=m;i++)
		{
			scanf("%d%d%d",&u,&v,&w);
			if(w<map[u][v])
			{
				map[u][v]=w;
				mapp[v][u]=w;
			}
				
				
		}
	//	printf("%d\n",n);
		Dijkstra();
		Dijkstra1();
		int max=-1;
		int f;
		for(i=1;i<=n;i++)
		{
			a[i]=d[i]+d1[i];
			
			if(d[i]>=INF||d1[i]>=INF)
			{
			//	printf("& ");
				continue;
			}
				
		//	printf("%d ",a[i]);
			
			if(max<a[i])
			{
				max=a[i];
				f=i;
			}
		}
		//printf("\n");
		printf("%d %d\n",f,max);
	}
	return 0;	
} 


猜你喜欢

转载自blog.csdn.net/gakki_wpt/article/details/78806515