题意:给一个图,如果图里有环或者是森林就输出"No"
注意空图算"Yes"
并查集判环:合并集合时,如果出现自己并自己的情况,就说明出现了环
1272:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int parent[maxn],ranc[maxn];
int serc(int pos)
{
while(parent[pos]!=pos)
{
pos=parent[pos];
}
return pos;
}
void init()
{
for(int i=0;i<=maxn;i++)
{
parent[i]=i;
ranc[i]=1;
}
}
void merg(int x,int y)
{
x=serc(x);
y=serc(y);
if(ranc[x]<ranc[y])
parent[x]=parent[y];
else
{
if(ranc[x]==ranc[y])ranc[x]++;
parent[y]=parent[x];
}
}
void compress(int pos)
{
int tpos=serc(pos);
int cur;
while(parent[pos]!=pos)
{
cur=parent[pos];
parent[pos]=tpos;
pos=cur;
}
}
bool s[maxn];
int main()
{
int t,m,n,cur1,cur2;
bool flag;
while(cin>>cur1>>cur2,cur1!=-1)
{
if(cur1==0&&cur2==0)
{
cout<<"Yes"<<endl;
}
else
{
memset(s,false,sizeof(s));
flag=false;
init();
int maxn=0;
if(cur1>maxn)maxn=cur1;
if(cur2>maxn)maxn=cur2;
s[cur1]=true;
s[cur2]=true;
if(serc(cur1)==serc(cur2))
flag=true;
merg(cur1,cur2);
while(cin>>cur1>>cur2,cur1!=0)
{
s[cur1]=true;
s[cur2]=true;
if(serc(cur1)==serc(cur2))flag=true;
merg(cur1,cur2);
if(cur1>maxn)maxn=cur1;
if(cur2>maxn)maxn=cur2;
}
int sum=0;
if(!flag)
for(int i=1;i<=maxn;i++)
{
if(parent[i]==i&&s[i]){if(sum==0)sum++;else{flag=true;break;}}
}
if(flag)cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
}
return 0;
}
1325把树搞成了有向边
只需要在上面那题代码里面加一个记录每个点有没有过双亲节点
//还有一点,输入结束标志是负数而不是-1 -1
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int parent[maxn],ranc[maxn];
bool hasparent[maxn];
int serc(int pos)
{
while(parent[pos]!=pos)
{
pos=parent[pos];
}
return pos;
}
void init()
{
for(int i=0;i<=maxn;i++)
{
parent[i]=i;
ranc[i]=1;
}
}
void merg(int x,int y)
{
x=serc(x);
y=serc(y);
if(ranc[x]<ranc[y])
parent[x]=parent[y];
else
{
if(ranc[x]==ranc[y])ranc[x]++;
parent[y]=parent[x];
}
}
void compress(int pos)
{
int tpos=serc(pos);
int cur;
while(parent[pos]!=pos)
{
cur=parent[pos];
parent[pos]=tpos;
pos=cur;
}
}
bool s[maxn];
int main()
{
int t,m,n,cur1,cur2,ppp=0;
bool flag;
while(cin>>cur1>>cur2,cur1>=0)
{
if(cur1==0&&cur2==0)
{
cout<<"Case "<<++ppp<<" is a tree."<<endl;
}
else
{
memset(s,false,sizeof(s));
memset(hasparent,false,sizeof(hasparent));
hasparent[cur2]=true;
flag=false;
init();
int maxn=0;
if(cur1>maxn)maxn=cur1;
if(cur2>maxn)maxn=cur2;
s[cur1]=true;
s[cur2]=true;
if(serc(cur1)==serc(cur2))
flag=true;
merg(cur1,cur2);
while(cin>>cur1>>cur2,cur1!=0)
{
if(!flag)
{
if(hasparent[cur2]){flag=true;}
hasparent[cur2]=true;
s[cur1]=true;
s[cur2]=true;
if(serc(cur1)==serc(cur2))flag=true;
merg(cur1,cur2);
if(cur1>maxn)maxn=cur1;
if(cur2>maxn)maxn=cur2;
}
}
int sum=0;
if(!flag)
for(int i=1;i<=maxn;i++)
{
if(parent[i]==i&&s[i]){if(sum==0)sum++;else{flag=true;break;}}
}
if(flag)cout<<"Case "<<++ppp<<" is not a tree."<<endl;
else cout<<"Case "<<++ppp<<" is a tree."<<endl;
}
}
return 0;
}