HDU - 6187 (最大生成树)

题目连接:

题意:国王的领土被分割成n个地方,国王想到达他领土的每一个地方,但是现在一些有一些城墙的隔绝两个地方,拆掉城墙需要耗费 一些财力物力,国王想拆最小的城墙数,花费最小的人力物力。给出的数据 ,开始给出的n个坐标值,(这个是唬人的,一点用都没有),而后给出 u  v w表示一个城墙连接的两个地方和拆掉需要耗费的代价了。

思路:这个题,当时翻译出了,我直接想到最是最小生成树,共有 n(n+1)/2 条路 ,其中给出的路是需要耗费代价的,没给出是不需要耗费代价的,这样建立最小生成树,但是数据太大,矩阵不能存储标记,而且排序和两层for会超时,这个方案就被舍弃了,比赛时,出现一点意外,我们就没继续深入解这个题。 上网搜题解:看到最大生成树,当时豁然开朗,n个地方最多n-1条路 ,再多加一条路,就会成圈。因此我们可以对立思考,保留下最大的生成树,这些就是不必要拆除的 ,余下的都需要拆除。还有一种可能,给出的数据够不成 最大的生成树,但是会构成圈 ,那么我们在建立最大生成树的时候,就会摒除构成圈的边(我在后来写这个题时就掉这个坑中,爬了好久,很菜),至于够不成最大的生成树,这个不用管,只需要它们够不成圈即可。

总结:可能是题刷的不够多,题型见的也不多吧,对于这种稍微变形的题,当时可能就做不出来,ACM比赛,可能不止比你的算法,更考你的发散思维吧。各种各样的题型,千奇百怪的解法,可以引导人发散的思维。

AC代码:

 

#include 
#include 
using namespace std;
#include 
#include 
int n,m;
int father[1100000];
struct node
{
	int x;
	int y;
	int k;
}Q[1100000];
int find(int x)
{
	if(father[x]==x)
	return x;
	return father[x]=find(father[x]);
}
bool cmp(node a,node b)
{
	return a.k>b.k;
}
int main()
{
	while(~scanf("%d %d",&n,&m))
	{
		int a,b;
		for(int i=1;i<=n;i++)
		{
			scanf("%d %d",&a,&b);
			father[i]=i;
		}
		int cont=0,sum=0,st=0;
		for(int i=0;i

你可能感兴趣的:(图论——最小生成树prime)