第三部分 數據結構 --第四章 圖論算法1348:【例4-9】城市公交網建設問題

1348:【例4-9】城市公交網建設問題

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

【題目描述】
有一張城市地圖,圖中的頂點爲城市,無向邊代表兩個城市間的連通關係,邊上的權爲在這兩個城市之間修建高速公路的造價,研究後發現,這個地圖有一個特點,即任一對城市都是連通的。現在的問題是,要修建若干高速公路把所有城市聯繫起來,問如何設計可使得工程的總造價最少?

【輸入】
n(城市數,1<≤n≤100)

e(邊數)

以下e行,每行3個數i,j,wij,表示在城市i,j之間修建高速公路的造價。

【輸出】
n-1行,每行爲兩個城市的序號,表明這兩個城市間建一條高速公路。

【輸入樣例】
5 8
1 2 2
2 5 9
5 4 7
4 1 10
1 3 12
4 3 6
5 3 3
2 3 8
【輸出樣例】
1 2
2 3
3 4
3 5


思路:這題就是輸出倆個城市之間的路,這裏我們用kruskal,輸入數據的時候要保證小的在前,是爲了輸出做準備的,這對題目是沒有影響的因爲並查集就是相當於無向圖。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 105;//最大點數 
const int M = 10000;//最大邊數 
int f[N];//並查集函數 
int cnt;//邊數 
struct node{
	int u;
	int v;
	int w;
}edge[M];//邊存儲內容,頂點 邊 權值 

void addedge(int u,int v, int w){//加邊
	edge[cnt].u = u;
	edge[cnt].v = v;
	edge[cnt++].w = w;
}
bool cmp(node a, node b){//排序函數
	return a.w < b.w;
}
int find(int x){//並查集
	if(f[x] == -1)
	return x;
	else
	return f[x] = find(f[x]);
}
int kruskal(int n)//傳入點數,返回最小生成樹的權值,如果不連通返回-1
{
	memset(f,-1,sizeof(f));
	sort(edge,edge+cnt,cmp);
	int sum = 0;//加入的邊數
	int  ans = 0;//權值的和
	for(int i = 0 ; i <= cnt; i++)
	{
		int u = edge[i].u;
		int v = edge[i].v;
		int w = edge[i].w;
		int t1 = find(u);
		int t2 = find(v);
		if(t1 != t2)
		{
			ans += w;
			f[t1] = t2;
			cout << u <<" "<<v << endl;
			sum++; 
		}
		if(cnt == n-1)
		break; 
	}
	if(sum < n - 1)//不聯通 
	return -1;
	else
	return ans;
 } 
 int main(){
 	int n,m;
 	cin >> n >> m;
 	cnt = 0;
 	for(int i = 0; i < m; i++)
 	{
 		int a,b,c;
 		cin >> a >> b >> c;
		 addedge(a,b,c); 
	 }
	 kruskal(n);
 	return 0;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章