题意:就是给你一些木棒,木棒两头都有颜色,颜色相同的可以连接起来。问你是否可以将所有
木棒连接起来。
思路:一看到这些字符串,就立马想到用map标记字符串的下标,直接超时。
然后使用快排+二分来查找这些字符的下标。
还有一个注意的地方,这是一个无向图。因为这个WA了好几次。
无向欧拉路连通的条件是:所有的度数都是偶数或者只有两个是奇数。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=550001;
int cnt_in[maxn],cnt_out[maxn],p[maxn];
int cnt_dushu[maxn];
char ss[maxn][20];
struct p
{
char s1[20],s2[20];
} tp[maxn];
int cnt=1,kj=0;
struct node
{
char str[20];
bool operator<(const node &c)const
{
return strcmp(str,c.str)<0;
}
} t[maxn];
int erfen(char *s)
{
int l=0,r=kj;
while(l<r)
{
int mid=(l+r)>>1;
if(strcmp(s,ss[mid])>0)
l=mid+1;
else
r=mid;
}
return l+1;
}
int cha(int x)
{
if(p[x]==x)
return x;
return p[x]=cha(p[x]);
}
void bing(int x,int y)
{
p[y]=x;
}
int main()
{
int n=0;
while(scanf("%s%s",tp[cnt].s1,tp[cnt].s2)!=EOF)
{
strcpy(t[n++].str,tp[cnt].s1);
strcpy(t[n++].str,tp[cnt].s2);
cnt++;
}
sort(t,t+n);
kj=0;
strcpy(ss[kj],t[0].str);
kj=1;
for(int i=1; i<n; i++)
if(strcmp(t[i].str,t[i-1].str)!=0)
strcpy(ss[kj++],t[i].str);
memset(cnt_dushu,0,sizeof(cnt_dushu));
for(int i=1; i<=kj; i++)
p[i]=i;
for(int i=1; i<cnt; i++)
{
int x=erfen(tp[i].s1);
int y=erfen(tp[i].s2);
//printf("%s %s\n",tp[i].s1,tp[i].s2);
//printf("%d %d\n",x,y);
cnt_dushu[x]++;
cnt_dushu[y]++;
x=cha(x);
y=cha(y);
if(x!=y)
bing(x,y);
}
int sum=0;
for(int i=1; i<=kj; i++)
if(p[i]==i)
sum++;
if(sum>1)
{
puts("Impossible");
return 0;
}
int f1=0,f2=0;
for(int i=1; i<=kj; i++)
{
if(cnt_dushu[i]%2==0)
f1++;
else f2++;
}
if(f1==kj)
{
puts("Possible");
}
else if(f1==kj-2&&f2==2)
{
puts("Possible");
}
else
{
puts("Impossible");
}
return 0;
}