PAT_1072. Gas Station(Dijkstra最短路)

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
const int maxint=99999;
struct yuandian
{
	int stationId;
	double cloestDist,averageDist;
}Hxd[15];
int N,M,K,D,hxdIndex=0;
int G[1024][1024];	//矩陣表示圖
bool s[1024];		//S集合
double dist[1024];	//dist數組(當前狀態下源點到其他所有點的最短路徑)
int cmp(yuandian a,yuandian b)
{
	if(a.cloestDist==b.cloestDist)
	{
		if(a.averageDist==b.averageDist)
			return a.stationId<b.stationId;
		else
			return a.averageDist<b.averageDist;
	}
	else
		return a.cloestDist>b.cloestDist;
}
void Dijkstra(int v)
{
	//初始化
	for(int i=1;i<=N+M;i++)
	{
		dist[i]=G[v][i];
		s[i]=false;
	}
	//將源點放入S集合
	s[v]=true;
	dist[v]=0;
	//將剩下的點放入S集合
	for(int i=2;i<=N+M;i++)
	{
		//找到一個點放入集合S
		int u;
		double mindist=maxint;
		for(int j=1;j<=N+M;j++)
		{
			if(s[j]==false&&dist[j]<mindist)
			{
				mindist=dist[j];
				u=j;
			}
		}
		s[u]=true;
		//更新dist數組
		for(int j=1;j<=N+M;j++)
			if(s[j]==false&&G[u][j]!=maxint&&dist[u]+G[u][j]<dist[j])
				dist[j]=dist[u]+G[u][j];
	}


	//本題邏輯
	Hxd[hxdIndex].cloestDist=dist[1];
	double sum=0;
	for(int i=1;i<=N;i++)
	{
		sum+=dist[i];
		if(dist[i]>D)
			return;
		if(dist[i]<Hxd[hxdIndex].cloestDist)
			Hxd[hxdIndex].cloestDist=dist[i];	
	}
	Hxd[hxdIndex].averageDist=sum/N;
	Hxd[hxdIndex].stationId=v;
	hxdIndex++;
}

int main()
{
	for(int i=1;i<1024;i++)
		for(int j=1;j<1024;j++)
			if(i==j)
				G[i][j]=0;
			else
				G[i][j]=maxint;

	scanf("%d%d%d%d",&N,&M,&K,&D);
	string a,b,c;
	for(int i=1;i<=K;i++)
	{
		cin>>a>>b>>c;
		int num1,num2;
		if(a[0]=='G')
			num1=N+atoi(a.substr(1).c_str());
		else
			num1=atoi(a.c_str());
		if(b[0]=='G')
			num2=N+atoi(b.substr(1).c_str());
		else
			num2=atoi(b.c_str());
		G[num1][num2]=G[num2][num1]=atoi(c.c_str());
	}

	//Dijkstra算法
	for(int i=N+1;i<=N+M;i++)
		Dijkstra(i);
	
	sort(Hxd,Hxd+hxdIndex,cmp);
	if(hxdIndex!=0)
		printf("G%d\n%.1lf %.1lf",Hxd[0].stationId-N,Hxd[0].cloestDist,Hxd[0].averageDist);
	else
		printf("No Solution");
	return 0;
}

 


這題顯然是要求解圖的某個點到圖的所有其他點的最短距離,因此不難想到Dijkstra算法,題目的細節挺多,要仔細地做。

在輸入的處理上,我用string接受輸入,判斷是否是候選點(候選點均爲G開頭),把形如G1,G2...GM的候選點轉換成數字(這與house的數量有關,

如G1=house的總數量+1,以此類推),建圖之後從第一個候選點開始調用Dijkstra算法,每次運算完畢都會得到一個dist數組,表示了從這個候選點

到其他所有house的最短距離,再按照題意完成相應的處理,保存在結構體數組中。

最後對這個結構體數組進行排序,優先級如下:

1.距離當前候選點最近的house的距離 大者優先

2.當前候選點與house的平均距離 小者優先

3.當前候選點的編號 小者優先


做這題之前沒有認認真真地學一遍Dijkstra算法,現在總算是掌握了。

回憶一次Dijkstra算法的思路:


Dijkstra算法主要維護一個S集合和一個U集合,S集合表示已經求出最短路徑的點,U集合表示還未求出最短路徑的點,Dijkstra的過程就是將U集合中的點慢慢

地加入到S集合中,在這個過程中源點到所有其他點的距離就被求出來了,如何從U集合中選擇恰當的點是Dijkstra算法的關鍵,挑選的依據是dist[]數組,這個

數組表示當前狀態下源點到其他點的最短路徑,每次選擇就選U集合中的與源點的最短路徑最小的那個點,加入S集合後,剛加入的點與源點的最短距離就已經

定下了,那麼以這個點爲中間點,再次更新dist數組,得到新的最短路徑,如此反覆,便可求出所有點到源點的最短路徑。


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