1. 程式人生 > >#1109 : 最小生成樹三·堆優化的Prim演算法

#1109 : 最小生成樹三·堆優化的Prim演算法

時間限制:10000ms 單點時限:1000ms 記憶體限制:256MB

描述

回到兩個星期之前,在成功的使用Kruscal演算法解決了問題之後,小Ho產生了一個疑問,究竟這樣的演算法在稀疏圖上比Prim優化之處在哪裡呢?

提示:沒有無緣無故的優化!

輸入

每個測試點(輸入檔案)有且僅有一組測試資料。

在一組測試資料中:

第1行為2個整數N、M,表示小Hi擁有的城市數量和小Hi篩選出路線的條數。

接下來的M行,每行描述一條路線,其中第i行為3個整數N1_i, N2_i, V_i,分別表示這條路線的兩個端點和在這條路線上建造道路的費用。

對於100%的資料,滿足N<=10^5, M<=10^6,於任意i滿足1<=N1_i, N2_i<=N, N1_i≠N2_i, 1<=V_i<=10^3.

對於100%的資料,滿足一定存在一種方案,使得任意兩座城市都可以互相到達。

輸出

對於每組測試資料,輸出1個整數Ans,表示為了使任意兩座城市都可以通過所建造的道路互相到達至少需要的建造費用。

樣例輸入
5 29
1 2 674
2 3 249
3 4 672
4 5 933
1 2 788
3 4 147
2 4 504
3 4 38
1 3 65
3 5 6
1 5 865
1 3 590
1 4 682
2 4 227
2 4 636
1 4 312
1 3 143
2 5 158
2 3 516
3 5 102
1 5 605
1 4 99
4 5 224
2 4 198
3 5 894
1 5 845
3 4 7
2 4 14
1 4 185
樣例輸出

92

題解:其實和克魯斯卡爾的思想一樣的,每次都查詢最小邊。由於使用了優先佇列,排序了使得複雜度降為了nlogn。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>

using namespace std;

const int INF = 100005;

struct Node
{
	int to;
	int dis;
	Node(int a,int b)
	{
		to = a;         //鄰接點 
		dis = b;
	}
    bool operator< (Node t) const  //排序 
    {
    	return dis > t.dis;
	}
};

vector<Node> vec[INF];
priority_queue<Node> q;
bool visited[INF];

void prime(int& ans,int n)
{
	for(int i = 0;i < vec[1].size();i++)     //與1相連的入隊 
	{
		q.push(vec[1][i]);
	}
	
	visited[1] = true;
	for(int i = 1;i < n;i++)       //n-1條邊 
	{
		while(!q.empty())        //每次找邊最小的 
		{
			Node t = q.top();
			q.pop();
			if(visited[t.to])
			{
				continue;
			}
			ans += t.dis;
			visited[t.to] = true;
			for(int j = 0;j < vec[t.to].size();j++) //更新佇列 
			{
				Node p = vec[t.to][j];
				if(!visited[p.to])
				{
					q.push(p);
				}
			}
			break;
		}
	}
	
	printf("%d\n",ans);
	
	for(int i = 1;i <= n;i++)
	{
		vec[i].clear();
	}
	
	while(!q.empty())
	{
		q.pop();
	}
}


int main()
{
	int n,m;
	int u,v,dis;
	cin>>n>>m;
	for(int i = 0;i < m;i++)
	{
		scanf("%d%d%d",&u,&v,&dis);
		vec[u].push_back(Node(v,dis));
		vec[v].push_back(Node(u,dis));
	}
	
	memset(visited,false,sizeof(visited));
	int ans = 0;
	
	prime(ans,n);
	
	
	return 0;
}