1272-题目:戳这里
1325-题目:戳这里
1272
任意两个房间有且仅有一条路径可以相通,用并查集找他们的队长,如果找到同一个就说明有两个房间有两条路相连,就可以直接输出No
最后在搜有几个部分,如果大于一,说明有的房间没有连起来
这题的输入比较麻烦,而且房间的号码也不是从一开始的,所以用set存房间的号码,因为set里没有重复的数字
1272代码:
#include <stdio.h> #include <string.h> #include <set> using namespace std; const int MAXN=100000+5; int re[MAXN],flag; set<int> p; int findd(int r) { while(re[r]!=r) r=re[r]; return r; } int main() { int a,b,sum; while(1) { memset(re,0,sizeof(re)); p.clear(); flag=0; while(scanf("%d%d",&a,&b)!=EOF) { if(a==-1&&b==-1)return 0; else if(a==0&&b==0) break; else { p.insert(a); p.insert(b); if(re[a]==0)re[a]=a; if(re[b]==0)re[b]=b; int ha=findd(a); int hb=findd(b); if(ha==hb)flag=1; else { re[ha]=hb; } } } sum=0; set<int> :: iterator it; for(it=p.begin();it!=p.end();it++) if(re[*it]==*it)sum++; if(flag==1||sum>1) printf("No\n"); else printf("Yes\n"); getchar(); } }
1325
1325与1272类似
但是1325是有向图,而1272是无向图
会出现这种情况
因此需要注意一下几点:
1.当输入两个负数时退出,不是当输出-1 -1 (这点不注意将一直超时)
2.对树的判断除了不成环,还需注意一个问题:此图为有向图:当b的根不是他自己或a时,b 这个节点有两个跟,同样不成数。
3.re[hb]=ha; 不可以是re[ha]=hb;因为a是父节点是根
1325代码:
#include <stdio.h> #include <string.h> #include <set> using namespace std; const int MAXN=100000+5; int re[MAXN]={0},flag; set<int> p; int findd(int r) { while(re[r]!=r) r=re[r]; return r; } int main() { int a,b,sum,t; t=1; while(1) { // memset(re,0,sizeof(re)); //不用memse,因为每次都要全部赋值太耗时了 p.clear(); flag=0; while(scanf("%d%d",&a,&b)!=EOF) { if(a<0||b<0)return 0; else if(a==0&&b==0) break; else { p.insert(a); p.insert(b); if(re[a]==0)re[a]=a; if(re[b]==0)re[b]=b; int ha=findd(a); int hb=findd(b); if(ha==hb||hb!=b)flag=1; else { re[hb]=ha; } } } sum=0; set<int> :: iterator it; for(it=p.begin(); it!=p.end(); it++) if(re[*it]==*it)sum++; for(it=p.begin();it!=p.end();it++) re[*it]=0; if(flag==1||sum>1) printf("Case %d is not a tree.\n",t++); else printf("Case %d is a tree.\n",t++); } }