HDU 1272小希的迷宮 1325Is It A Tree? 並查集確定圖為樹

來源:互聯網
上載者:User

這兩題主要是解決一個圖是否是樹的問題。

有很多細節需要注意。

1、空樹也是樹。

2、一個圖若是樹需滿足兩個條件:

①連通分量為一;

②圖中無環,包括自環和非自環。

3、邊數+1=頂點數。

以上幾點只是針對無向圖的,1272題就是解決無向圖是否是樹的問題。而如果要判斷有向圖是否是樹,還要判斷

頂點的入度。滿足入度為0的點只有一個,以及入度都不大於1。1325題就是判斷有向圖是否是樹的問題。

 

1272   AC代碼:

#include<iostream>using namespace std;const int MAX=100001;int father[MAX];bool flag[MAX],flagLC;void initial()    //初始化{for(int i=1;i<MAX;i++)father[i]=i;}int find(int x)    //尋找{while(father[x]!=x)x=father[x];return x;}void combine(int a,int b)   //合并{int tmpa=find(a);int tmpb=find(b);if(tmpa!=tmpb)father[tmpa]=tmpb;else        flagLC=true;    //a,b在同一個連通分量中,說明有環}int main(){int i,a,b,connectedComponent,edgeNum,nodeNum;bool flagCircle;  //自環while(1){initial();edgeNum=0;  //邊數flagLC=flagCircle=false;   //標誌是否有環        memset(flag,false,sizeof(flag));   //標誌在圖內的點,在為true        scanf("%d%d",&a,&b);if(a==0 && b==0)   //空樹{cout<<"Yes"<<endl;continue;}if(a==-1 && b==-1) break;if(a==b) flagCircle=true;flag[a]=true;flag[b]=true;        edgeNum++;        combine(a,b);while(1){scanf("%d%d",&a,&b);if(a==0 && b==0) break;            if(a==b) flagCircle=true;flag[a]=true;flag[b]=true;            edgeNum++;combine(a,b);}connectedComponent=0;        //連通分量數        nodeNum=0;    //點數for(i=1;i<MAX;i++)   //判斷圖是否連通,tmp=1連通{if(flag[i]){nodeNum++; //計算圖內包含的所有點if(father[i]==i)connectedComponent++;}}if(connectedComponent==1 && nodeNum==edgeNum+1 && !flagCircle && !flagLC)  //連通的無環圖為樹cout<<"Yes";elsecout<<"No";cout<<endl;}return 0;}

 

1325  AC代碼:

#include<iostream>using namespace std;const int MAX=100001;int father[MAX];bool flag[MAX],flagLC;int in[MAX];  //存放頂點入度void initial()    //初始化{for(int i=1;i<MAX;i++)father[i]=i;}int find(int x)    //尋找{while(father[x]!=x)x=father[x];return x;}void combine(int a,int b)   //合并{int tmpa=find(a);int tmpb=find(b);if(tmpa!=tmpb)father[tmpa]=tmpb;else        flagLC=true;    //a,b在同一個連通分量中,說明有環}int main(){int i,a,b,connectedComponent,edgeNum,nodeNum,cas=1;bool flagCircle;  //自環while(1){initial();edgeNum=0;  //邊數flagLC=flagCircle=false;   //標誌是否有環        memset(flag,false,sizeof(flag));   //標誌在圖內的點,在為truememset(in,0,sizeof(in));        scanf("%d%d",&a,&b);if(a==0 && b==0)   //空樹{cout<<"Case "<<cas++<<" is a tree."<<endl;continue;}if(a<0 && b<0) break;if(a==b) flagCircle=true;flag[a]=true;flag[b]=true;        edgeNum++;        combine(a,b);in[b]++;   //入度加1while(1){scanf("%d%d",&a,&b);if(a==0 && b==0) break;            if(a==b) flagCircle=true;flag[a]=true;flag[b]=true;            edgeNum++;combine(a,b);in[b]++; //入度加1}connectedComponent=0;        //連通分量數        nodeNum=0;    //點數for(i=1;i<MAX;i++)   //判斷圖是否連通,tmp=1連通{if(flag[i]){nodeNum++; //計算圖內包含的所有點if(father[i]==i)connectedComponent++;}}int numZero=0,numMore=0;for(i=0;i<MAX;i++){if(flag[i]){if(in[i]==0)  //入度為0的點即根只能有一個numZero++;else if(in[i]>1)   //不能有入度大於1的點numMore++;}}if(connectedComponent==1 && nodeNum==edgeNum+1 && !flagCircle && !flagLC && numZero==1 && numMore==0) //連通無環並且滿足入度條件 cout<<"Case "<<cas++<<" is a tree.";elsecout<<"Case "<<cas++<<" is not a tree.";cout<<endl;}return 0;}

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.