hdu 1879 继续畅通工程
2013-02-15 20:28
411 查看
跟前几题畅通工程类似,求最小生成树。当状态是已修建时,直接merge。值得注意的是得用scanf,用cin会超时。还得用路径压缩的并查集,不然也会TLE。
#include<iostream> #include<algorithm> using namespace std;//20:07 #define NUM 102 struct points { int start; int end; int w; }pos[5050]; int set[NUM]; void init() { for(int i=0;i<NUM;++i) set[i]=i; } int find(int x) { int r=x; while(r!=set[r]) r=set[r]; return r; } int find2(int x)//带路径压缩的查找(非递归版) { int k, j, r; r = x; while(r != set[r]) //查找根节点 r = set[r]; //找到根节点,用r记录下 k = x; while(k != r) //非递归路径压缩操作 { j = set[k]; //用j暂存set[k]的父节点 set[k] = r; //set[x]指向根节点 k = j; //k移到父节点 } return r; //返回根节点的值 } void merge(int x,int y) { int a=find2(x); int b=find2(y); if(a!=b) set[a]=b; return; } int cmp(struct points a,struct points b) { return a.w < b.w; } int main() { int n,i,m,index,x,y,weight,status,sum; freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin); //while(cin>>n&&n!=0){ while(scanf("%d",&n)!=EOF&&n!=0){ m=n*(n-1)/2; index=0; sum=0; init(); while(m--){ cin>>x>>y>>weight>>status; if(status==1) merge(x,y); else { pos[index].start=x; pos[index].end=y; pos[index].w=weight; ++index; } } sort(pos,pos+index,cmp); for(i=0;i<index;++i){ if(find2(pos[i].start)!=find2(pos[i].end)){ merge(pos[i].start,pos[i].end); sum+=pos[i].w; } } //cout<<sum<<endl; printf("%d\n",sum); } return 0; }
相关文章推荐
- HDU 1879 继续畅通工程(最小生成树Kruskal)
- HDU1879 继续畅通工程(Prim算法)
- HDU 1879 继续畅通工程(Kruskra)
- HDU 1879 继续畅通工程
- HDU 1879 继续畅通工程
- HDU1879---继续畅通工程
- HDU_1879_继续畅通工程
- hdu1879 继续畅通工程(最小生成树)
- hdu 1879 继续畅通工程
- HDU 1879 继续畅通工程
- 继续畅通工程(HDU 1879)
- HDU 1879 继续畅通工程(Kruskra)
- HDU 1879 继续畅通工程
- HDU 1879 继续畅通工程(最小生成树 Kruskal)
- hdu 1879 继续畅通工程
- HDU - 1879 [继续畅通工程] 最小生成树Kruskal
- HDU 1879 继续畅通工程
- HDU 1879 继续畅通工程 最小生成树P算法
- HDU -1879-继续畅通工程
- hdu 1879 继续畅通工程(Kruskal)