#include<iostream> #include<cstring> #include<string> #include<cstdio> #include<algorithm> using namespace std; #define MAX 80000 int father[MAX], son[MAX]; int v,v2, l; struct Kruskal //存储边的信息 { int a; int b; int value; }; bool cmp(const Kruskal & a, const Kruskal & b) { return a.value < b.value; } int unionsearch(int x) //查找根结点+路径压缩 { return x == father[x] ? x : unionsearch(father[x]); } bool join(int x, int y) //合并 { int root1, root2; root1 = unionsearch(x); root2 = unionsearch(y); if(root1 == root2) //为环 return false; else if(son[root1] >= son[root2]) { father[root2] = root1; son[root1] += son[root2]; } else { father[root1] = root2; son[root2] += son[root1]; } return true; } //int mhash[MAX]; int main() { int ltotal, sum; int i,flag; Kruskal edge[MAX]; scanf("%d%d%d", &v,&v2, &l); ltotal = 0, sum = 0, flag = 0; for(i = 0; i < v+v2; ++i) //初始化 { father[i] = i; son[i] = 1; // mhash[i]=0; } int tem,temva; for(i = 1; i <= l ; ++i) { scanf("%d%d%d", &edge[i].a, &tem, &temva); edge[i].b=tem+v; edge[i].value=-temva; } sort(edge + 1, edge + 1 + l, cmp); //按权值由小到大排序 for(i = 1; i <= l; ++i) { if(join(edge[i].a, edge[i].b)) { // mhash[edge[i].a]=1; // mhash[edge[i].b]=1; ltotal++; //边数加1 sum += edge[i].value; //记录权值之和 // cout<<edge[i].a<<"->"<<edge[i].b<<endl; } // if(ltotal == v+v2 - 1) //最小生成树条件:边数=顶点数-1 // { // flag = 1; // break; // } } // int s=0; // for(i=0;i<v+v2;i++){ // if(mhash[i])s++; // } printf("%d\n",(v+v2)*10000+sum); // if(flag) printf("%d\n", sum); // else printf("data error.\n"); return 0; } /* 5 5 8 4 3 6831 1 3 4583 0 0 6592 0 1 3063 3 3 4975 1 3 2049 4 2 2104 2 2 781 */
版权声明:本文为博主原创文章,未经博主允许不得转载。
today lazy . tomorrow die .