这个题的大致思路是 先判断 是否在同集内,如果输入的两个在,那么标为NO,如果这样还不能确定结果,那么用判断是否联通来确定,另外注意的就是0 0的情况 和 标记 数组(判断是否出现,因为最后判断联通,是连续的)的问题。
/* 功能Function Description: HDOJ-1272 开发环境Environment: vc6.0 技术特点Technique: 版本Version: 作者Author: jzjz 日期Date: 20120814 备注Notes: 并查集 */ #include<stdio.h> #include<string.h> int flat,bin[100001]; int find(int i) { int t=i; while(bin[t]!=t) t=bin[t]; return t; /* int k,t; t=i; while(t!=bin[t]) t=bin[t]; while(i!=t) //修改路径---压缩 { k=bin[i]; bin[i]=t; i=k; } return i;*/ } void insert(int x,int y) { int fx,fy; fx=find(x); fy=find(y); if(fx==fy) flat=1; else bin[fx]=fy; } int main() { int a,b,i,min,max,c[100001]; while(scanf("%d%d",&a,&b)&&(a!=-1||b!=-1)) { flat=-1; memset(c,-1,sizeof(c)); if(a==0&&b==0) { printf("Yes\n"); continue; } else if(a==b) flat=1; max=a>b?a:b; min=a<b?a:b; if(max<(a>b?a:b)) max=a>b?a:b; if(min>(a<b?a:b)) min=a<b?a:b; for(i=0;i<100001;i++) bin[i]=i; bin[a]=b; c[a]=c[b]=1;///////标记指针 是否出现 while(scanf("%d%d",&a,&b)&&(a!=0||b!=0)) { c[a]=c[b]=1; if(flat==1) continue; if(max<(a>b?a:b)) ///找出大至区间 max=a>b?a:b; if(min>(a<b?a:b)) min=a<b?a:b; insert(a,b); } if(flat==1) printf("No\n"); else { for(i=min;i<=max;i++) if(bin[i]==i&&c[i]==1) flat++; if(flat==0) printf("Yes\n"); else printf("No\n"); } } return 0; }
此题和南阳OJ上129题目一样,当时没用并查集,利用STL 动态数组来模拟数 的,现在看来有点麻烦了,呵呵
http://acm.nyist.net/JudgeOnline/problem.php?pid=129
代码:
1 2 #include<stdio.h> 3 #include<string.h> 4 #include<set> 5 #include<vector> 6 using namespace std; 7 vector<vector<int> >v; 8 vector<int > iv; 9 set<int >s,ss; 10 int tree[10010]; 11 12 int dfs(int start) 13 { 14 int id; 15 id=0; 16 iv.push_back (start); 17 vector<int >::iterator i; 18 while(1) 19 { 20 for(i= v[iv[id]].begin ();i!=v[iv[id]].end ();++i) 21 { 22 if(!tree[*i]) 23 { 24 tree[*i]=1; 25 iv.push_back (*i); 26 ss.insert (*i); 27 } 28 } 29 id++; 30 if(s==ss) 31 return 1; 32 if(id==iv.size ()) 33 return 0; 34 } 35 } 36 37 38 int main() 39 { 40 int n,m,in[10010],start,count=0; 41 v.assign(10010,vector<int >()); 42 memset(in,0,sizeof(in)); 43 while(scanf("%d%d",&n,&m)) 44 { 45 if(n==-1&&m==-1) 46 break; 47 else if(n==0&&m==0) 48 { 49 count++; 50 int r=1,r2=0; 51 memset(tree,0,sizeof(tree)); 52 set<int >::iterator i; 53 for(i = s.begin ();i!=s.end ();++i) 54 { 55 if(in[*i]>1) 56 { 57 r=0;; 58 break; 59 } 60 else if(in[*i]==0) 61 { 62 r2++; 63 start=*i; 64 } 65 } 66 if(s.empty ()) 67 { 68 printf("Case %d is a tree.\n",count); 69 continue; 70 } 71 if(r&&r2==1) 72 { 73 if(dfs(start)) 74 printf("Case %d is a tree.\n",count); 75 else 76 printf("Case %d is not a tree.\n",count); 77 } 78 else 79 printf("Case %d is not a tree.\n",count); 80 memset(tree,0,sizeof(tree)); 81 memset(in,0,sizeof(in)); 82 s.clear (); 83 ss.clear(); 84 v.clear (); 85 iv.clear (); 86 v.assign (10000,vector<int >()); 87 88 } 89 else 90 { 91 in[m]++; 92 s.insert (n); 93 s.insert (m); 94 v[n].push_back (m); 95 v[m].push_back (n); 96 } 97 } 98 return 0; 99 } 100 101 102