19北郵計算機-C 城市道路 //最短路徑

時間限制 1000 ms 內存限制 65536 KB

題目描述

計算從城市1到城市n的最短路徑長度。分爲白天和黑夜,黑夜會關掉若干條線路,分別計算城市1到城市n的在白天和黑夜的最短路徑長度。保證每個城市與其他城市必有連接。兩個城市之間可能有多條路。

輸入格式
第一行爲數據組數T
對於每組測試數據

第一行三個整數,n,m,k. (1<=n<=50)n表示城市個數,m表示道路個數,k表示黑夜需要關閉的道路個數。

接下來m行,每行 三個整數 x,y,c (1<=x,y<=n),其中第 i 行(1<=i <=m)表示第 i 條道路爲從城市x到城市y長度爲c(可能存在重複邊)。

接下來k行,每行一個整數w,表示黑夜要關閉的道路編號。

輸出格式
每組數據輸出兩行

第一行爲白天從城市1到城市n的最短距離

第二行爲黑夜從城市1到城市n的最短距離

輸入樣例

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

 輸出樣例

1
3
4
6

代碼1://Floyed弗洛伊德實現,因爲n<=50,O(n^3)不會超時

#include<bits/stdc++.h>
using namespace std;
struct B
{
	int x,y,c;
}b[1003];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m,k,i,j,w,x,y,c;
		int d1[53][53],d2[53][53];
		memset(d1,-1,sizeof(d1));//最大值用-1表示 若用0x7f表示 可能與另一個整數相加超出int的最大值 得到負值 則導致出錯 
		memset(d2,-1,sizeof(d2));//或是存儲路徑用long long數組 然後用memset(d,0x7f,sizeof(d));初始化 
		scanf("%d%d%d",&n,&m,&k);
		for(i=1;i<=m;++i)
		{
			scanf("%d%d%d",&x,&y,&c);
			b[i].x=x;
			b[i].y=y;
			b[i].c=c;
			if(d1[x][y]==-1)
			{
				d1[x][y]=d1[y][x]=c;
			}
			else if(d1[x][y]>c)
			{
				d1[y][x]=d1[x][y]=c;
			}
		}
		for(i=0;i<k;++i)
		{
			scanf("%d",&w);
			b[w].x=b[w].y=b[w].c=-1;
		}
		for(i=1;i<=m;++i)
		{
			
			if(b[i].x!=-1)
			{
				x=b[i].x;
				y=b[i].y;
				c=b[i].c;
				if(d2[x][y]==-1)
				{
					d2[x][y]=d2[y][x]=c;
				}
				else if(d2[x][y]>c)
				{
					d2[x][y]=d2[y][x]=c;
				}
			}
			
		}
		//Floyed弗洛伊德 
		for(int z=1;z<=n;++z)
		{
			for(i=1;i<=n;++i)
			{
				for(j=1;j<=n;++j)
				{
					if(d1[i][z]!=-1&&d1[z][j]!=-1)
					{
						if(d1[i][j]!=-1)
						d1[i][j]=min(d1[i][j],d1[i][z]+d1[z][j]);
						else d1[i][j]=d1[i][z]+d1[z][j];
					}
					if(d2[i][z]!=-1&&d2[z][j]!=-1)
					{
						if(d2[i][j]!=-1)
						d2[i][j]=min(d2[i][j],d2[i][z]+d2[z][j]);
						else d2[i][j]=d2[i][z]+d2[z][j];
					}
				}
			}
		}
		printf("%d\n%d\n",d1[1][n],d2[1][n]);
	}
} 

代碼2: //Dijkstra迪傑斯特拉 

#include<bits/stdc++.h>
using namespace std;
struct B
{
	int x,y;
	long long c;
}b[1003];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m,k,i,j,w,x,y,z[53];
		long long c,d1[53][53],d2[53][53],dis1[53],dis2[53];
		memset(d1,0x7f,sizeof(d1));//最大值用-1表示 若用0x7f表示 可能與另一個整數相加超出int的最大值 得到負值 則導致出錯 
		memset(d2,0x7f,sizeof(d2));//或是存儲路徑用long long數組 然後用memset(d,0x7f,sizeof(d));初始化 
		memset(dis1,0x7f,sizeof(dis1));
		memset(dis2,0x7f,sizeof(dis2));
		
		scanf("%d%d%d",&n,&m,&k);
		for(i=1;i<=m;++i)
		{
			scanf("%d%d%lld",&x,&y,&c);
			b[i].x=x;
			b[i].y=y;
			b[i].c=c;
			d1[x][y]=d1[y][x]=min(c,d1[x][y]);
			
		}
		for(i=0;i<k;++i)
		{
			scanf("%d",&w);
			b[w].x=b[w].y=b[w].c=-1;
		}
		for(i=1;i<=m;++i)
		{
			
			if(b[i].x!=-1)
			{
				x=b[i].x;
				y=b[i].y;
				c=b[i].c;
				d2[x][y]=d2[y][x]=min(c,d2[x][y]);
			}	
		}
		//Dijkstra迪傑斯特拉 
		for(i=2;i<=n;++i)
		{
			dis1[i]=d1[1][i];
			dis2[i]=d2[1][i];
		}
		memset(z,0,sizeof(z));
		z[1]=1;
		for(i=1;i<n;++i)
		{
			int mi=0x7fffffff,z1=-1;
			for(j=2;j<=n;++j)
			{
				if(!z[j]&&dis1[j]<mi)
				{
					mi=dis1[j];
					z1=j;
				}
			}
			if(z1!=-1)
			{
				z[z1]=1;
				dis1[z1]=mi;
				if(z1==n)break;
				for(j=2;j<=n;++j)
				{
					if(!z[j])
					{
						dis1[j]=min(dis1[j],mi+d1[z1][j]);
					}
				}
			}
		}
		printf("%lld\n",dis1[n]);
		
		memset(z,0,sizeof(z));
		z[1]=1;
		for(i=1;i<n;++i)
		{
			int mi=0x7fffffff,z2=-1;
			for(j=2;j<=n;++j)
			{
				if(!z[j]&&dis2[j]<mi)
				{
					mi=dis2[j];
					z2=j;
				}
			}
			if(z2!=-1)
			{
				z[z2]=1;
				dis2[z2]=mi;
				if(z2==n)break;
				for(j=2;j<=n;++j)
				{
					if(!z[j])
					{
						dis2[j]=min(dis2[j],mi+d2[z2][j]);
					}
				}
			}
		}
		printf("%lld\n",dis2[n]);
	}
}
		

 

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