POJ 2513

View Code
 1 /*
2 问题:给出一些两端染有颜色木棒,
3 把这些木棒以相同的颜色对接
4 是否能形成一条直线
5 思路:
6 1.输入 以文件结束
7 2.利用字符串hash ,在hash表中存放的
8 是这是第几个端点,也能表明在这位置的端点
9 是否出现过
10 3.并查集判断连通性
11 4.看是否存在欧拉路
12
13 呵呵,没想到数组开这么大,用了hash记录点 竟然一次过了,欣喜,加油!!!
14 */
15 #include<iostream>
16 #include<cstdio>
17 #include<cstring>
18 using namespace std;
19 const int MA=250001;
20 int a[MA+10];
21 int degree[MA+10];
22 int father[MA+10];
23 int rank[MA+10];
24 char str1[11],str2[11];
25 int point;//记录总点数
26
27 int find(int n)
28 {
29 int i=n;
30 while(i!=father[i])
31 i=father[i];
32 int j=n;
33 while(j!=i)
34 {
35 int k=father[j];
36 father[j]=i;
37 j=k;
38 }
39 return i;
40 }
41 void uion(int x,int y)
42 {
43 x=find(x);
44 y=find(y);
45 if(x==y)return;
46 if(rank[x]>rank[y])
47 {
48 rank[x]+=rank[y];
49 father[y]=x;
50 }
51 else
52 {
53 rank[y]+=rank[x];
54 father[x]=y;
55 }
56 }
57
58 int hash(const char *k)
59 {
60 unsigned long int te=0;
61 while(*k)
62 {
63 te=(te<<5)+te+*k++;
64 }
65 return te%MA;
66 }
67 int main()
68 {
69 int i,x,y,h1,h2;
70 point=0;
71 memset(degree,0,sizeof(degree));
72 memset(a,-1,sizeof(a));
73 for(i=0;i<MA;++i)
74 {
75 father[i]=i;
76 rank[i]=1;
77 }
78 while(scanf("%s%s",str1,str2)!=EOF)
79 {
80 h1=hash(str1);
81 h2=hash(str2);// point 记录端点数 每新增加一个颜色 point 加 1 表明新增一个顶点
82 if(a[h1]==-1){point++;a[h1]=point;degree[point]++;}
83 else degree[a[h1]]++;// a[i]==-1;表明这是新出现的颜色
84 if(a[h2]==-1){point++;a[h2]=point;degree[point]++;}
85 else degree[a[h2]]++;// 若a[i]!=-1 说明这个颜色出现过 他所代表的顶点序号就是a[h2]
86 uion(a[h1],a[h2]);
87 }
88 int k=0;// 记录度数为奇数的点的个数
89 bool flag=0;
90 for(i=1;i<=point;++i)
91 {
92 if(degree[i]%2)k++;
93 if(rank[father[i]]!=point)flag=1;
94 }
95 if((!k||k==2)&&!flag)printf("Possible\n");
96 else printf("Impossible\n");
97 system("pause");
98 return 0;
99 }

 

posted @ 2012-02-10 23:24  知行执行  阅读(208)  评论(0编辑  收藏  举报