///数组f初始化:
for(int i=1;i<=n;i++) f[i]=i;///n为顶点个数,1到n为顶点编号
int find(int x){///递归
if(f[x]==x) return x;
else return find(f[x]);
}
int find(int x){///非递归
while(x!=f[x]) x=f[x];
return x;
}
查找优化:路径压缩。把当前查询路径上的所有结点的父亲都指向根结点,查找的时候就不需要每次都回塑去找父亲了。复杂度就可以降为O(1)了。
int find(int x){///非递归
int p=x;///把x保存下来
while(f[x]!=x) x=f[x];///寻找根节点
while(f[p] != p){///路径压缩
int t = p;
p = f[p];///回溯父亲结点
f[t] = x;///将结点t改为根节点x
}
return x;
}
int find(int x){///递归版
if(x == f[x]) return x;
else{
int t = find(f[x]);///找根节点
f[x] = t;
return t;
}
}
void mergex(int x,int y){
int fa,fb;
fa=getf(x);
fb=getf(y);
if(fa!=fb){
f[fa]=fb;///f[fb]=fa同样可以
}
合并的优化:
///a[] 记录每个根节点对应的树的深度(如果不是根节点,其a相当于以它作为根节点的子树的深度)
void mergex(int x,int y){
if((x=find(x))==find(y)) return;
if(a[x]>=a[y]) f[y]=x;///数组a初始化为1
else{
f[x]=y;
if(a[x]==a[y]) a[y]++;///如果深度相同且根节点不同,则新的根节点的深度+1
}
}
#include
int f[1010];
int find(int x){///找根节点
if(x!=f[x]) f[x] = find(f[x]);
return f[x];
}
int merge(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx!=fy) f[fx] = fy;
}
int main(){
int n,m;
while(~scanf("%d",&n)&&n){
scanf("%d",&m);
for(int i=1;i<=n;i++) f[i] = i;
int u,v;
while(m--){
scanf("%d%d",&u,&v);
merge(u,v);
}
int ans = 0;
for(int i=1;i<=n;i++)
if(i==find(i)) ans++;
printf("%d\n",ans-1);///除了根结点
}
return 0;
}
#include
#include
int f[100010];
bool flag;
int find(int x){///找根节点
if(x==f[x]) return x;
else return find(f[x]);
}
int merge(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx!=fy) f[fy] = fx;
else flag = true;
}
int main(){
while(1){
int u,v;
int sum = 0;
flag = false;
memset(f,0,sizeof(f));
while(scanf("%d%d",&u,&v)&&u&&v){
if(u==-1&&v==-1) return 0;
if(f[u]==0) f[u] = u;
if(f[v]==0) f[v] = v;
merge(u,v);
}
for(int i=1;i<100010;i++)
if(f[i]==i) sum++;
if(sum>1||flag==true) printf("No\n\n");
else printf("Yes\n\n");
}
return 0;
}
#include<stdio.h>
#include<string.h>
#include<map>
#include<string>
#include<iostream>
using namespace std;
map <string,int> ma;
int num[100010];
int f[100010];
int find(int x){
if(f[x]!=x) f[x] = find(f[x]);
return f[x];
}
int merge(int x,int y){
int fx = find(x);
int fy = find(y);
if(fx!=fy) {
f[fx] = fy;
num[fy]+=num[fx];
printf("%d\n",num[fy]);
}
else printf("%d\n",num[fy]);
}
int main(){
int t;
while(scanf("%d",&t)!=EOF){
while(t--){
int n;
scanf("%d",&n);
ma.clear();
for(int i=0;i<100010;i++) {
f[i] = i;
num[i] = 1;
}
string name1,name2;
int len=1;
for(int i=0;i<n;i++){
///scanf("%s %s",&name1,&name2);
cin>>name1>>name2;
if(!ma[name1]) ma[name1] = len++;
if(!ma[name2]) ma[name2] = len++;
if(name1==name2) {
printf("%d\n",num[find(ma[name1])]);
continue;
}
merge(ma[name1],ma[name2]);
}
}
}
return 0;
}
#include<stdio.h>
int f[2010],num[2010];
bool flag;
int find(int x){
if(x==f[x]) return x;
int temp = find(f[x]);
num[x] = (num[x]+num[f[x]])%2;
f[x] = temp;
return temp;
}
void merge(int u,int v){
int fu,fv;
fu = find(u);
fv = find(v);
if(fu==fv) {
if(num[u]==num[v]) flag = false;///找到同性昆虫
return;
}
f[fv] = fu;
num[fv] = (num[u]+1-num[v]+2)%2;
}
int main(){
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++){
int n,m;
scanf("%d%d",&n,&m);
flag = true;
for(int j=1;j<=n;j++){
f[j] = j;
num[j] = 0;
}
for(int j=1;j<=m;j++){
int u,v;
scanf("%d%d",&u,&v);
if(flag) merge(u,v);
}
printf("Scenario #%d:\n",i);
if(flag) printf("No suspicious bugs found!\n\n");
else printf("Suspicious bugs found!\n\n");
}
return 0;
}