POJ 1386 Play on Words
欧拉回路问题。
题意是说给你一些字符串。类似于成语接龙,上一个字符串尾字母必须和下一个字符串首字母同样。
把全部字符串连成一串。
依据定理推断欧拉通路。然后DFS判连通(并查集也可)
没注意题意 字符串开了str[100] 结果RE。结果字符串最长有1000.改了就AC了。
DFS:
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<iostream>
#include<list>
#include<set>
#include<cmath>
#define INF 0x7fffffff
#define eps 1e-6
using namespace std;
int n,m;
int g[27][27];
int in[27],out[27];
bool vis[27];
int start;
bool Euler()
{
int I=0,O=0;
for(int i=0; i<26; i++)
{
if(in[i]==out[i]+1)I++;
else if(out[i]==in[i]+1)O++,start=i;
else if(in[i]!=out[i])return 0;
}
if((I==0&&O==0)||(I==1&&O==1))return 1;
return 0;
}
void dfs(int i)
{
int j;
for( j=0; j<26; j++)
{
if(g[i][j]==0)continue;
g[i][j]--;
vis[i]=vis[j]=1;
dfs(j);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&m);
char str[1001];
memset(g,0,sizeof(g));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(int i=0; i<m; i++)
{
scanf("%s",str);
int u=str[0]-'a';
int v=str[strlen(str)-1]-'a';
g[u][v]++;
in[v]++,out[u]++;
}
for(int i=0;i<26;i++)
if(out[i]>0){start=i;break;}
bool flag=1;
flag=Euler();
if(!flag)
{
puts("The door cannot be opened.");
continue;
}
memset(vis,0,sizeof(vis));
dfs(start);
for(int i=0; i<26; i++)
{
if(in[i]||out[i])
{
if(vis[i]==0)
{
flag=0;
break;
}
}
}
if(flag)puts("Ordering is possible.");
else puts("The door cannot be opened.");
}
}
并查集:
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<algorithm>
#include<map>
#include<stack>
#include<iostream>
#include<list>
#include<set>
#include<cmath>
#define INF 0x7fffffff
#define eps 1e-6
#define LL long long
using namespace std;
int in[26],out[26];
int fa[26];
int n;
bool vis[26];
int father(int x)
{
if(x!=fa[x])
return fa[x]=father(fa[x]);
}
bool Euler()
{
int I=0,O=0;
for(int i=0;i<26;i++)
{
if(!vis[i]||in[i]==out[i])continue;
if(out[i]-1==in[i])O++;
else if(in[i]-1==out[i])I++;
else return 0;
}
if(O==1&&I==1)return 1;
if(O==0&&I==0)return 1;
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
for(int i=0;i<26;i++)
{
in[i]=out[i]=vis[i]=0;
fa[i]=i;
}
scanf("%d",&n);
char str[1001];
for(int i=0;i<n;i++)
{
scanf("%s",str);
int len=strlen(str);
int u=str[0]-'a';
int v=str[len-1]-'a';
vis[u]=vis[v]=1;
out[u]++,in[v]++;
u=father(u),v=father(v);
if(u==v)continue;
fa[v]=u;
}
bool flag=0;
flag=Euler();
if(!flag)
{
puts("The door cannot be opened.");
continue;
}
else
{
int block=0;
for(int i=0;i<26;i++)
{
if(vis[i]&&father(i)==i)block++;
if(block>1){flag=0;break;}
}
if(!flag)puts("The door cannot be opened.");
else puts("Ordering is possible.");
}
}
}
浙公网安备 33010602011771号