题目大意:
中文题,是一个求最小生成树的模板题,需要判是否连通。
解题思路:
都说了是模板题,写个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; }