M - 小希的迷宮HDU - 1272
題意:
輸入很多條邊,要你判斷這些邊連成的迷宮不存在環。
思路:
- 自環的情況,當兩個點如果他們的祖先相同,此時再將他們並在一起,會導致內環。
- 特判:輸入0 0 時要輸出yes。
AC( 3. 我考場時的代碼):
我當時想沒有環,那麼 邊數+1= 點數。
#include <iostream>
#include <cstdio>
#include <cstring>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
#define mst(x,a) memset(x,a,sizeof(x))
using namespace std;
const int maxn=1e5+10;
int max_num=0,flag;
int f[maxn],in[maxn];
int find(int x)
{
if(f[x]==-1)return x;
return f[x]=find(f[x]);
}
void merge(int u, int v)
{
int uf=find(u);
int vf=find(v);
max_num=max(u,max(max_num,v));
if(uf!=vf)f[uf]=vf;
else flag=0;
}
int main()
{
int n,m,ed=0;
while(~scanf("%d%d", &n,&m))
{
if(n==0)
{
printf("Yes\n");//特判
continue;
}
ed=max_num=0;
flag=1;
if(n==m&&n==-1)break;
mst(f,-1);
mst(in,0);
merge(n,m);
ed++;
while(scanf("%d%d",&n,&m)&&(n|m))
{
merge(n,m);
ed++;
}
For(i,1,max_num)in[find(i)]++;
if(in[find(max_num)]==ed+1&&flag)printf("Yes\n");
else printf("No\n");
}
return 0;
}
AC(4. 考慮是否只有一個集合)
#include <iostream>
#include <cstdio>
#include <cstring>
#define For(i,x,y) for(register int i=(x); i<=(y); i++)
#define mst(x,a) memset(x,a,sizeof(x))
using namespace std;
const int maxn=1e5+10;
int max_num=0,flag;
int f[maxn],vis[maxn];
int find(int x)
{
if(f[x]==-1)return x;
return f[x]=find(f[x]);
}
void merge(int u, int v)
{
int uf=find(u);
int vf=find(v);
vis[u]=vis[v]=1;
max_num=max(u,max(max_num,v));
if(uf!=vf)f[uf]=vf;
else flag=0;
}
int main()
{
int n,m,cnt=0;
while(~scanf("%d%d", &n,&m))
{
if(n==0)
{
printf("Yes\n");
continue;
}
cnt=max_num=0;
flag=1;
if(n==m&&n==-1)break;
mst(f,-1);
mst(vis,0);
merge(n,m);
while(scanf("%d%d",&n,&m)&&(n|m))
{
merge(n,m);
}
For(i,1,max_num)
{
if(vis[i]&&find(i)==i)cnt++;
}
if(cnt==1&&flag)printf("Yes\n");
else printf("No\n");
}
return 0;
}