/*
此题用了我一天,说明我的基础知府还是不够扎实;
考点:
欧拉回路和欧拉通路, 加变相DNF;
前提:要是连通图;(用dnf,(每一步两头搜))
欧拉回路,要求图的每一个点的出度和入度一样,
欧拉通路,要求图的起点的出度比入度大1,终点的出度比入度少于1;
*/
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
const int MAX = 26;
int map[MAX][MAX];
int visit_in[MAX];
int visit_out[MAX];
int flag[MAX];
int M;
char str[1005];
void down(int n);
//图的遍历,向上搜
void up(int sa){
flag[sa] = 0;
for(int i=0; i<26; ++i){
if(map[i][sa] > 0){
--map[i][sa];
up(i);
down(sa);
}
}
}
//图的遍历,向下搜
void down(int sb){
flag[sb] = 0;
for(int i=0; i<26; ++i){
if(map[sb][i] > 0){
--map[sb][i];
up(i);
down(i);
}
}
}
int main(){
int T;
int a,b,len,sa,sb;
scanf("%d",&T);
while(T--){
memset(visit_in, 0, sizeof(visit_in));
memset(visit_out, 0, sizeof(visit_out));
memset(map, 0, sizeof(map));
memset(flag, 0, sizeof(flag));
scanf("%d",&M);
//转成邻接矩阵
int num = M;
scanf("%s",str);
len = strlen(str);
sa = a = str[0]-97;
sb = b = str[len-1]-97;
flag[a] = flag[b] = 1;
++visit_out[a];
++visit_in[b];
++map[a][b];
while(--num){
scanf("%s",str);
len = strlen(str);
a = str[0]-97;
b = str[len-1]-97;
flag[a] = flag[b] = 1;
++visit_out[a];
++visit_in[b];
++map[a][b];
}
//用第一个点开始遍历;
--map[sa][sb];
up(sa);
down(sb);
//判断有点或边没有遍历完的
int res = 0;
for(int i=0; i<26; ++i){
if(flag[i] == 1){
res = 1;
break;
}
}
for(int i=0; (i<26) && (res==0); ++i){
for(int j=0; j<26; ++j){
if(map[i][j]){
res = 1;
break;
}
}
}
if(res == 1){
printf("The door cannot be opened.\n");
continue ;
}
//判断点的出度和入度是否符合要求;
res = 0;
a = b = 0;
for(int i=0; i<26; ++i){
if(visit_out[i] != visit_in[i]){
res++;
if( ( visit_out[i] > visit_in[i] ) && (visit_out[i] - visit_in[i] == 1) )
a = 1;
if( ( visit_out[i] < visit_in[i] ) && (visit_in[i] - visit_out[i] == 1) )
b= 1;
}
}
if(res == 0 || (res == 2 && a == 1 && b==1 )){
printf("Ordering is possible.\n");
}else{
printf("The door cannot be opened.\n");
}
}
return 0;
}
POJ 1386(欧拉回路,欧拉通路,变相DNF)
最新推荐文章于 2021-05-14 23:51:02 发布