九度教程77 dijkstra算法之《單源最短路徑》

題目地址:http://ac.jobdu.com/problem.php?cid=1040&pid=76


//九度教程77 dijkstra算法之《單源最短路徑》
//http://ac.jobdu.com/problem.php?cid=1040&pid=76
#include<stdio.h>
#define MAXN 1047483640//
typedef struct E{
	int min;
	int spend;
}E;
E mm[1001][1001],value[1001];
int main()
{
	int a,b,i,j,n,m,k,s,t,temps,tempm;
	while(~scanf("%d %d",&n,&m)&&n)
	{
		for(i=0;i<=n;i++)
		{
			flag[i]=1;//1爲還沒進集合,0爲已進集合
			value[i].min=value[i].spend=MAXN;
			for(j=0;j<=n;j++)mm[i][j].min=mm[i][j].spend=MAXN;
		}
		for(i=0;i<m;i++)//讀入m條邊
		{
			scanf("%d %d",&a,&b);
			scanf("%d %d",&tempm,&temps);
			if(a==b||tempm>mm[a][b].min||tempm==mm[a][b].min&&temps>=mm[a][b].spend)continue;//考慮自環及重邊。無視自環及權值較大的重邊
			mm[a][b].min=tempm;mm[a][b].spend=temps;
			mm[b][a]=mm[a][b];
		}
		scanf("%d %d",&s,&t);
		flag[s]=0;//初始只包含s這個結點集合
		value[k=s].min=value[s].spend=0;//起始點的最短路min爲0,花費spend爲0;k初值爲起始點s。
		while(k!=t)
		{
			for(i=k,j=1;j<=n;j++)
			{
				if(j==k)continue;
				if(value[j].min>value[k].min+mm[k][j].min)
				{
					value[j].min=value[k].min+mm[k][j].min;
					value[j].spend=value[k].spend+mm[k][j].spend;
				}
				else if(value[j].min==value[k].min+mm[k][j].min)
				{
					if(value[j].spend>value[k].spend+mm[k][j].spend)
						value[j].spend=value[k].spend+mm[k][j].spend;
				}
			}
			for(k=1;flag[k]==0;k++);//把k指向某一個未被包含的頂點,爲了下步做準備。
			for(i=1;i<=n;i++){if(flag[i]&&(value[k].min>value[i].min||value[k].min==value[i].min&&value[k].spend>value[i].spend))k=i;}
			flag[k]=0;//設置已把k包含進來的標誌
		}
		printf("%d %d\n",value[k].min,value[k].spend);
	}
	return 0;
}


發佈了57 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章