POJ 1861 Network (Kruskal算法)

这道题目其实是最小生成树的题目。

但是题目给的样例有误导嫌疑,所以可能比较难的看出来。

一开始读题目,看样例,看了很久,怎么对也好样例不一样。

后面只好仔细在看一遍题目。发现题目讲的是,把任意两个点连通起来。

那么这个就是最小生成树的定义。

于是就按照最小生成树的样子写了一下。最后过了

证明确实题目给的样例确实是错的。

好好读题目才是关键

最后输出的是,最小生成树最长边,边数,以及每一条边

 

#include<iostream>
#include<algorithm>
#include<functional>
#include<cstdio>
#include<cstring>
#define maxn 150005
using namespace std;
struct node
{
	int from,to,cost;
}edge[maxn];
int n,m,fa[10005];
int k,ans[maxn];
int mx,cnt;
int cmp(struct node a,struct node b){return a.cost<b.cost;}//结构体从小到大排序
void init()//并查集初始化
{
	memset(edge,0,sizeof(edge));
	memset(ans,0,sizeof(ans));
	k=1;
	cnt=0;
	mx=-99999999;
	for(int i=1;i<=n;i++)
		fa[i]=i;
}
int getfa(int x)//找父亲节点
{
	if(x==fa[x])
		return x;
	return fa[x]=getfa(fa[x]);
}
int merge(int u,int v)//如果可以合并就合并,再返回1
{
	int t1,t2;
	t1=getfa(u);
	t2=getfa(v);
	if(t1!=t2)
	{
		fa[t1]=t2;
		return 1;
	}
	return 0;
}
int main()
{
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		init();
		for(i=1;i<=m;i++)
			scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].cost);
		sort(edge+1,edge+m+1,cmp);//传的是地址
//		for(i=1;i<=m;i++)
//		printf("From:%d To:%d Cost:%d\n",edge[i].from,edge[i].to,edge[i].cost);

		for(i=1;i<=m;i++)
		{
//			printf("ans=%d\n",merge(edge[i].from,edge[i].to));
			if(merge(edge[i].from,edge[i].to))
			{
				mx=max(edge[i].cost,mx);
				ans[k++]=edge[i].from;
				ans[k++]=edge[i].to;
				cnt++;
			}
		}

		printf("%d\n",mx);
		printf("%d\n",cnt);
		for(i=1;i<k;i+=2)
			printf("%d %d\n",ans[i],ans[i+1]);
	}
	return 0;
}

全部评论

相关推荐

11-09 11:01
济南大学 Java
Java抽象带篮子:外卖项目真得美化一下,可以看看我的详细的外卖话术帖子
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务