P1195 口袋的天空(并查集+Kruskal)

来源:互联网 发布:js 什么时候使用链表 编辑:程序博客网 时间:2024/05/16 11:57

P1195 口袋的天空
题目概述:给定一张含有N个节点,M条边的图,将图中的节点通过边连为K个部分,边权即为连接边上的两断电所需要的代价,如果能够满足题意,求最小总代价,反之输出“No Answer”。
数据范围:1<=N<=1000,1<=M<=10000,1<=K<=10,0<=L<10000
思路:Kruskal+并查集,边界为连接边数t==n-k时结束算法。
代码:

#include<cstring>#include<cstdio>#include<cstdlib>#include<iostream>#include<queue>#include<algorithm>using namespace std;int i,j,k,n,m,ans,kk;int fa[10005];struct data{    int x,y,v;}a[100005];queue<int>x,y;int r(){    int aans=0,f=1;    char ch=getchar();    while(ch<'0'||ch>'9')    {        if(ch=='-')            f=-1;        ch=getchar();    }    while(ch>='0'&&ch<='9')    {        aans*=10;        aans+=ch-'0';        ch=getchar();    }    return aans*f;}int cmp(data aa,data bb){    if(aa.v<bb.v) return 1;    return 0;}int findd(int xx){    if(fa[xx]==xx) return fa[xx];    return fa[xx]=findd(fa[xx]);}void unionn(int xx,int yy){    int fx=findd(xx),fy=findd(yy);    fa[fx]=fy;}void kruskal(){    int t=0;    for(i=1;i<=m;i++)    {        if(findd(a[i].x)!=findd(a[i].y))        unionn(a[i].x,a[i].y),t++,ans+=a[i].v;        if(t==n-k)        {cout<<ans;kk=1;        return;}    }}int main(){    n=r(),m=r(),k=r();    for(i=1;i<=m;i++)    {        a[i].x=r(),a[i].y=r(),a[i].v=r();    }    for(i=1;i<=n;i++)    fa[i]=i;    sort(a+1,a+m+1,cmp);    kruskal();    if(!kk)    cout<<"No Answer";    return 0;}                

这里写图片描述

原创粉丝点击