poj 1386 play on words
http://poj.org/problem?id=1386
问题描述:有向图欧拉路径的存在性
欧拉路径
【无向图】连通 + 每个顶点的度数都为偶数 或 仅有两个点的度数为偶数
【有向图】连通 + 每个顶点的入度 = 出度 或 有且仅有一个顶点的入度比出度多1同时一个顶点的出度比入度多1,其余出度等于入度
思路
并查集判断图的连通性(此时看成无向图即可)+欧拉路径的出入度判断
参考代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int _max = 1e2 + 10;
int n,in[_max],out[_max],pre[_max];
char s[1010];
bool vis[_max];
bool elpath(){//欧拉路径(有向图)
int f1 = 0,f2 = 0;
for(int i = 1; i <= 26; ++ i){
if(vis[i]){
if(in[i]-out[i]>=2 || out[i] - in[i] >=2) return false;
if(in[i]==out[i]+1){
if(f1 == 0) f1 = 1;
else return false;
}
if(in[i]==out[i]-1){
if(f2 == 0) f2 = 1;
else return false;
}
}
}
if(f1 + f2 == 1) return false;
return true;
}
void init(){ //并查集部分
for(int i = 1; i <= _max; ++ i) pre[i] = i;
}
int find(int x){
return pre[x]==x?x:pre[x]=find(pre[x]);
}
void join(int a,int b){
int x = find(a), y = find(b);
if(x!=y) pre[x] = y;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
#endif // ONLINE_JUDGE
int T;cin>>T;
while(T--){
scanf("%d",&n);
fill(in,in+_max,0);
fill(out,out+_max,0);
fill(vis,vis+_max,false);
init();
for(int i = 0; i < n; ++ i){
scanf("%s",s);
int l = strlen(s);
int u = s[0]-'a'+1, v = s[l-1]-'a'+1;//1~26
vis[u] = vis[v] = 1;
join(u,v);
out[u]++;//入度 出度
in[v]++;
}
int cnt = 0;
for(int i = 1; i <= 26; ++ i) if(pre[i] == i&&vis[i]) cnt++;
if(cnt != 1){puts("The door cannot be opened.");continue;}
puts(elpath()?"Ordering is possible.":"The door cannot be opened.");
}
return 0;
}
- 加粗
Ctrl + B
- 斜体
Ctrl + I
- 引用
Ctrl + Q
- 插入链接
Ctrl + L
- 插入代码
Ctrl + K
- 插入图片
Ctrl + G
- 提升标题
Ctrl + H
- 有序列表
Ctrl + O
- 无序列表
Ctrl + U
- 横线
Ctrl + R
- 撤销
Ctrl + Z
- 重做
Ctrl + Y