程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> A Bugs Life hdu1829 並查集

A Bugs Life hdu1829 並查集

編輯:C++入門知識

    本題為二分的並查集,其實只要在原先的並查集基礎上作一下變形。當然此題也還是有技巧的,我們可以對每個節點做個標記,若該節點與父親節點屬於同一類,則標記為,0,否則標記為1。但當我們合並兩棵樹時,可能會存在兩棵樹的標記所表達的意思完全相反,此時我們就要通過改變其中一棵樹根節點的標記,來保持合並之後的樹保持一致。   至於何時有同性戀發生,應該不難判斷了,若兩個節點屬於同一棵樹且屬於同一類則發生同性戀。   [cpp]  #include<iostream>   #include<cstdio>      using namespace std;   const int maxn=2005;   int set[maxn],flag[maxn];   //set[i]記錄i的父親節點,flag[i]==0表示該節點的性別與父親節點相同,否則不相同      void init(int n)   {       for(int i=1;i<=n;i++)       {           set[i]=i;           flag[i]=0;       }   }      int find1(int x)//返回父親節點   {       while(set[x]!=x)           x=set[x];       return x;   }      int find2(int x)//返回0或1,判斷該節點與根節點是否一致   {       int t=0;       while(set[x]!=x)       {           t^=flag[x];           x=set[x];       }       return t;   }      bool merge(int x,int y)//合並   {       int f1=find1(x);       int f2=find1(y);       if(f1==f2)           return false;       set[f1]=f2;       //如果兩棵樹定義有沖突,則使它們一致(此處通過改變flag[f1])       if(find2(x)==find2(y))           flag[f1]^=1;       return true;   }      int main()   {       int t,n,m,a,b,C=1;       bool state;       scanf("%d",&t);       while(t--)       {           scanf("%d%d",&n,&m);           init(n);           state=true;           while(m--)           {               scanf("%d%d",&a,&b);               if(!state)                   continue;               if(!merge(a,b)&&(find2(a)^find2(b))==0)//同一棵樹且性別相同的兩個節點                   state=false;           }           printf("Scenario #%d:\n",C++);           if(!state)               printf("Suspicious bugs found!\n");           else               printf("No suspicious bugs found!\n");           printf("\n");//每個樣例後面都換行,坑爹的地方       }       return 0;   }      

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved