1028.繼續暢通工程

題目描述:
省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可)。現得到城鎮道路統計表,表中列出了任意兩城鎮間修建道路的費用,以及該道路是否已經修通的狀態。現請你編寫程序,計算出全省暢通需要的最低成本。
輸入:
測試輸入包含若干測試用例。每個測試用例的第1行給出村莊數目N ( 1< N < 100 );隨後的 N(N-1)/2 行對應村莊間道路的成本及修建狀態,每行給4個正整數,分別是兩個村莊的編號(從1編號到N),此兩村莊間道路的成本,以及修建狀態:1表示已建,0表示未建。

當N爲0時輸入結束。
輸出:
每個測試用例的輸出佔一行,輸出全省暢通需要的最低成本。
樣例輸入:
3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0
樣例輸出:
3
1

0


思路:如果已建成,將花費置爲0,否則爲題目給定花費。然後求最小生成樹。

#include <iostream>
#include <algorithm>

using namespace std;

const int MaxInt = 9999;
const int MaxNum = 1000;

int c[MaxNum][MaxNum];  //鄰接矩陣
int dist[MaxNum];       //每個節點到源點的最短距離
bool visited[MaxNum];   //每個節點是否訪問過

void Prim(int s,int n)
{
	for(int i = 1; i <= n; ++i)
		dist[i] = c[s][i];

	dist[s] = 0;
	visited[s] = true;

	//依次訪問接下來的n - 1個unknown節點
	for(int i = 1; i <= n - 1; ++i)
	{
		int tmp = MaxInt; //當前最短距離
		int v = s; // 當前的節點

		//在所有unknown節點中找到和源點距離最短的節點
		for(int j = 1; j <= n; ++j)
		{
			if(!visited[j] && dist[j] < tmp)
			{
				v = j;
				tmp = dist[j];
			}
		}

		//找到了和源點距離最短的unknown節點,更改其訪問數組
		visited[v] = true;

		//然後更新其鄰接的邊,所有的邊都要訪問一次,都可能會更新
		for(int j = 1; j <= n; ++j)
		{
			if(!visited[j] && c[v][j] < MaxInt)
			{
				dist[j] = min(dist[j],c[v][j]);  //prim算法!!
			}
		}
	}
}

int main()
{
	int n;  // n代表節點數目
	while(cin >> n)
	{
		//跳出條件
		if(n == 0)
			break;
		int line = n * (n - 1) / 2;
		//初始化鄰接矩陣
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= n; ++j)
				c[i][j] = MaxInt;

		for(int i = 0; i < line; ++i)
		{
			int p,q,len;
			bool state;
			cin >> p >> q >> len >> state;
			if(len < c[p][q])//如果有重邊
			{
				c[p][q] = len;
				c[q][p] = len;  //無向圖 如果有向圖這句話就去掉
			}
			if(state == 1)
            {
                c[p][q] = 0;
                c[q][p] = 0;
            }
		}

		//初始化最短距離
		for(int i = 1; i <= n; ++i)
			dist[i] = MaxInt;

		//初始化訪問數組
		for(int i = 1; i <= n; ++i)
			visited[i] = false;

		Prim(1,n);
		int min_dist = 0;

		for(int i = 1; i <= n; ++i)
			min_dist += dist[i];

		cout << min_dist << endl;

	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章