hdu3047 Zjnu Stadium(帶权并查集 详细图解)?

来源:互联网 发布:mac唇釉价格 编辑:程序博客网 时间:2024/06/06 08:43

分析如下:先将各个点对union起来得到如下图解:



上图最下面是最终路径压缩后的结果。

此程序仅供参考,过不了OJ,想要过OJ 的话请去其他博客看源代码。

#include<stdlib.h>#include<stdio.h>#define N 50005int pre[N],dis[N];void init1(int n){     for(int i=0;i<=n;i++)     {         pre[i]=i;         dis[i]=0;     }}void myunion(int a,int b,int dist,int fa,int fb){     pre[fb]=fa;//合并     dis[fb]=dis[a]+dist-dis[b];//同时更新fb到新根的距离,以使a与b的距离刚好等于dist }int find(int x){    if(pre[x]!=x)    {        int tem=pre[x];        pre[x]=find(pre[x]);//路径压缩         dis[x]+=dis[tem];//dis[x]+=父亲节点到根的距离 。这样就是X到根的距离         return pre[x];//每次返回都是同一个数 ,即这个集合的根     }    return x;   }int main(){    int i,n,m,u,v,dist,count=0,fa,fb;    while(scanf("%d%d",&n,&m)!=EOF)    {      init1(n);      for(i=1;i<=m;i++)      {        scanf("%d%d%d",&u,&v,&dist);        fa=find(u);        fb=find(v);        if(fa!=fb)           myunion(u,v,dist,fa,fb);        else           if(dist!=dis[v]-dis[u])//在同一棵树上               count++;           }            printf("%d\n",count);    }      //system("pause");      return 0;    }/*这是我改过的数据,测试正确,不过不知道为什么程序过不了杭电OJ10 101 2 1503 4 2001 5 4302 6 2006 5 804 7 1508 9 1004 8 501 7 1009 2 50*/