这题想了很久,还是没做出来,看了一下网上的题解,原来是把字母当成点,用
单词代表关系,这样建立并查集,检查连通性。如果连通,则检查是否存在欧拉
通路,注意欧拉回路也是欧拉通路一种,离散数学的知识:
要么所有点入度等于出度;
要么有且只有两个点,一个是入度比出度大一,另一个一个是出度比入度大一,
其余的点都相等;
140ms代码
#include<iostream>
#include<string>
typedef struct charter
{
long int in;
long int out;
int father;
}charter;
charter bin[27];
int v[27];
int find(int x)
{
while(x!=bin[x].father)
x=bin[x].father;
return x;
}
int merge(int x,int y)
{
int fx,fy;
fx=find(x);
fy=find(y);
if(fx!=fy)
{
bin[fy].father=fx;
}
return 0;
}
int main()
{
int t,i,flag,iflag,oflag,x,y,root;
long int n;
char c[1002];
scanf("%d",&t);
while(t--)
{
scanf("%ld",&n);
flag=iflag=oflag=root=0;
for(i=0;i<26;i++)
{
bin[i].father=i;
bin[i].in=0;
bin[i].out=0;
v[i]=0;
}
for(i=0;i<n;i++)
{
scanf("%s",c);
x=c[0]-'a';
bin[x].out++;
y=c[strlen(c)-1]-'a';
bin[y].in++;
merge(x,y);
v[x]=v[y]=1;
}
for(i=0;i<26;i++)
{
if(v[i]==1&&bin[i].father==i)
root++;
}
if(root!=1)
{
printf("The door cannot be opened.\n");
}
else
{
for(i=0;i<26;i++)
{
if(bin[i].in==bin[i].out+1)
{
iflag++;
}
else if(bin[i].out==bin[i].in+1)
{
oflag++;
}
else if((bin[i].in>bin[i].out+1)||(bin[i].out>bin[i].in+1))
{
flag=1;
break;
}
}
if(flag!=1&&((iflag==0&&oflag==0)||(iflag==1&&oflag==1)))
{
printf("Ordering is possible.\n");
}
else
{
printf("The door cannot be opened.\n");
}
}
}
return 0;
}
单词代表关系,这样建立并查集,检查连通性。如果连通,则检查是否存在欧拉
通路,注意欧拉回路也是欧拉通路一种,离散数学的知识:
要么所有点入度等于出度;
要么有且只有两个点,一个是入度比出度大一,另一个一个是出度比入度大一,
其余的点都相等;
140ms代码
#include<iostream>
#include<string>
typedef struct charter
{
long int in;
long int out;
int father;
}charter;
charter bin[27];
int v[27];
int find(int x)
{
while(x!=bin[x].father)
x=bin[x].father;
return x;
}
int merge(int x,int y)
{
int fx,fy;
fx=find(x);
fy=find(y);
if(fx!=fy)
{
bin[fy].father=fx;
}
return 0;
}
int main()
{
int t,i,flag,iflag,oflag,x,y,root;
long int n;
char c[1002];
scanf("%d",&t);
while(t--)
{
scanf("%ld",&n);
flag=iflag=oflag=root=0;
for(i=0;i<26;i++)
{
bin[i].father=i;
bin[i].in=0;
bin[i].out=0;
v[i]=0;
}
for(i=0;i<n;i++)
{
scanf("%s",c);
x=c[0]-'a';
bin[x].out++;
y=c[strlen(c)-1]-'a';
bin[y].in++;
merge(x,y);
v[x]=v[y]=1;
}
for(i=0;i<26;i++)
{
if(v[i]==1&&bin[i].father==i)
root++;
}
if(root!=1)
{
printf("The door cannot be opened.\n");
}
else
{
for(i=0;i<26;i++)
{
if(bin[i].in==bin[i].out+1)
{
iflag++;
}
else if(bin[i].out==bin[i].in+1)
{
oflag++;
}
else if((bin[i].in>bin[i].out+1)||(bin[i].out>bin[i].in+1))
{
flag=1;
break;
}
}
if(flag!=1&&((iflag==0&&oflag==0)||(iflag==1&&oflag==1)))
{
printf("Ordering is possible.\n");
}
else
{
printf("The door cannot be opened.\n");
}
}
}
return 0;
}