hdoj/hdu 1863 畅通工程(最小生成树 Prim+优先队列)

超级传送门:

http://acm.hdu.edu.cn/showproblem.php?pid=1863

 

题目大意:

就是给一个图各个边的大小,求最小生成树,没什么特别

 

题目分析:

既然没什么特别就,当做练习,不再拷贝模板,手敲。。

一手敲还是出现很多问题的:

居然define 错误写成 #define inf = 900000000; 居然出现两个错

头文件忘记包含queue,vector,两个都不要忘了

while(visited[edge.v] != 0 && !pq.empty() ); 这里也曾经敲错了,而且,答案居然还是正确的,交上去就超时,要谨慎!

明天再拿其他题目再敲敲。。。

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

#define inf 900000000

const int MAXN = 120;

struct XEdge  
{  
    int v; //边端点   
    int w; //边权值   
    XEdge(int v_ = 0, int w_ = inf):v(v_),w(w_) { }  
};  

vector < vector<XEdge> > G(MAXN);

operator < (const XEdge e1,const XEdge e2)
{
	return e1.w > e2.w;
}

int HeapPrim(const vector< vector <XEdge> > G , int n)
{
	int i;
	XEdge edge(1,0);
	priority_queue<XEdge> pq;
	vector<int> dis(MAXN);
	vector<int> visited(MAXN);

	int nDone = 0;
	int ans = 0;

	

	//初始化
	for(i=1;i<=n;i++)
	{
		dis[i] = inf;
		visited[i] = 0;
	}
	pq.push(edge);

	//找最短边,
	while(nDone < n && !pq.empty())
	{
		do
		{
			edge = pq.top();
			pq.pop();
		}while(visited[edge.v] != 0 && !pq.empty() );

		if(visited[edge.v] == 0)
		{
			//找到一条最短的边,加进最小生成树中
			ans += edge.w;
			visited[edge.v] = 1;
			nDone++;

			//修改
			for(i=0;i<G[edge.v].size();i++)
			{
				int k = G[edge.v][i].v;
				if(visited[k] == 0)
				{
					if(dis[k] > G[edge.v][i].w)
					{
						dis[k] = G[edge.v][i].w;
						pq.push(XEdge(k,dis[k]));
					}
				}
			}
		}
	}

	if(nDone < n)
	{
		return -1;
	}
	else
	{
		return ans;
	}
}

int main()
{

	int N,M;
	int a,b,c;
	int i;
	int sum;
	while(scanf("%d",&N) != EOF)
	{
		if(N == 0) break;
		scanf("%d",&M);
		
		for(i=0;i<N;i++)
		{
			scanf("%d %d %d",&a,&b,&c);
			G[a].push_back(XEdge(b,c));
			G[b].push_back(XEdge(a,c));
		}
		sum = HeapPrim(G,M);
		if(sum == -1)
		{
			printf("?\n");
		}
		else
		{
			printf("%d\n",sum);
		}
		G.clear();
		G.resize(MAXN);
	}
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值