1. 程式人生 > >openjudge1308——Is It A Tree?

openjudge1308——Is It A Tree?

題目連結:http://bailian.openjudge.cn/practice/1308?lang=en_US

題目大意:給你一個集合,判斷它是不是一顆樹(無環,點的個數=邊的個數+1,空樹)並查集判斷即可

解釋都在程式碼裡

 

#include<bits/stdc++.h>

#define rd(x) x=read()
#define N 1000005

using namespace std;
 
int Case=1;
int f[N];
int find(int x)
{
    if(x!=f[x])f[x]=find(f[x]);
    return f[x]; 
}
//find函式 map<int,int>vis;//記錄節點是否出現過 int cnt_v,cnt_e;//記錄點與邊的數量 inline int read() { int f=1,x=0;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } void init() { cnt_v=0,cnt_e=0; for
(int i=0;i<N;i++)f[i]=i; vis.clear(); }//初始化 bool check() { if(cnt_v&&cnt_v!=cnt_e+1)return false;//如果不為空樹且節點數不等於邊數+1 return true; }//判斷是否滿足 void addEdge(int a,int b) { if(!vis[a])cnt_v++; if(!vis[b])cnt_v++; cnt_e++,vis[a]=1,vis[b]=1; }//加邊 void merge(int a,int b) {
int x=find(a),y=find(b); if(x!=y)f[x]=y; }//合併 int main() { init();//初始化 int a,b; while(cin>>a>>b) { if(a==-1&&b==-1)return 0;//如果均為-1,結束 else if(a==0&&b==0)//如果一個case結束 { if(check())printf("Case %d is a tree.\n",Case++);//滿足 else printf("Case %d is not a tree.\n",Case++);//不滿足 init(); //再次初始化 } else if(a||b)addEdge(a,b);//如果有一個點不為0,加邊 else merge(a,b);//否則歸併 } return 0;//一定要往下看 }

 

讀者可以試試,把這份程式碼提交,等待你的不是AC而是WA

為什麼呢?

一路寫下來沒有什麼問題呀?

有問題,有很大問題。

當我們符合最後一條(66行),要考慮一個問題,有沒有可能既要歸併,又要加邊?

所以,要把65行的 else if 提前,提到最前!!!(沒有正確AC程式碼提供,請讀者自行修改上面那段程式碼)