HDU 1863 畅通工程(kruskal)

题目大意:

中文题,是一个求最小生成树的模板题,需要判是否连通。


解题思路:

都说了是模板题,写个kruskal模板就能过,所有的点都操作过即说明这个图一定连通。


#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<set>
#define LL long long
#define db double
#define maxn 10000000
#define EPS 1e-15
#define max(a,b) ((a>b)?(a):(b))
#define min(a,b) ((a<b)?(a):(b))
using namespace std;

int p[110],m,n,sum;
struct Fuck{
    int u,v,w;
}fuck[110],tmp;
int find(int x){
    return x==p[x]?p[x]:find(p[x]);
}
void qsort(int l,int r){
    int ll,rr,mid;
    ll=l; rr=r; mid=(fuck[ll].w+fuck[rr].w)>>1;
    while (ll<=rr){
        while (fuck[ll].w<=mid) ll++;
        while (fuck[rr].w>=mid) rr--;
        if (ll<=rr){
                tmp=fuck[ll];
                fuck[ll]=fuck[rr];
                fuck[rr]=tmp;
        }
    }
    if (l<rr) qsort(l,rr);
    if (r<ll) qsort(r,ll);
}
void Kruskal(){
    int i,ans=0;
    for(i=1;i<=m;i++)
    p[i]=i;
    qsort(1,n);
    for(i=1;i<=n;i++){
        int x=find(fuck[i].u);
        int y=find(fuck[i].v);
        if(x!=y){
            sum++;
            ans+=fuck[i].w;
            p[x]=y;
        }
    }
    if(sum==m)
    printf("%d\n",ans);
    else
    printf("?\n");
}
int main(){
    while(1){
        scanf("%d%d",&n,&m);
        if (n==0) break;
        int i;
        sum=1;
        for(i=1;i<=n;i++)
        scanf("%d%d%d",&fuck[i].u,&fuck[i].v,&fuck[i].w);
        Kruskal();
    }
    return 0;
}




你可能感兴趣的:(HDU 1863 畅通工程(kruskal))