标签:false 初始 etc 判断 clear http getc 链接 c代码
题目链接: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代码提供,请读者自行修改上面那段代码)
标签:false 初始 etc 判断 clear http getc 链接 c代码
原文地址:https://www.cnblogs.com/Robin20050901/p/10152222.html