POJ1386Play on Words(歐拉回路)
阿新 • • 發佈:2018-11-13
轉自:POJ1386Play on Words(歐拉回路)
【題意】這個就相當於成語接龍,需滿足前一個單詞的尾字母與後一個的首字母相同。然後就是問是否 存在尤拉通路。
【分析】用兩個陣列存每個字母的入度與出度,再用vis[]判斷字母是否出現,然後並查集判斷是否聯通。
定理1:無向圖G存在尤拉通路的條件是:G為連通圖,並且G只有兩個奇度節點或者無奇度節點。
推論1:(1)當G是僅有兩個奇度節點的連通圖時,G的尤拉通路必以此兩個節點為端點。
(2)當G是無奇度節點連通圖時,G比為歐拉回路。
(3)G為尤拉圖(存在歐拉回路)的充要條件是G為無奇度節點的連通圖。
定理2:有向圖D存在尤拉通路的充要條件是:D為有向圖,D的基圖聯通,並且所有頂點的出度與入度都相等;或者除兩個頂 點外 其餘頂點的出度與入度都相等,而這兩個頂點中一個頂點的出度-入度==1,另一個出度-入度==-1;
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <climits> #include <cstring> #include <string> #include <set> #include <map> #include <queue> #include <stack> #include <vector> #include <list> #include<functional> #define mod 1000000007 #define inf 0x3f3f3f3f #define pi acos(-1.0) using namespace std; typedef long long ll; const int N=100005; const int M=150005; char str[N]; int n,m; int vis[27],pre[27]; int out[27],in[27]; struct man { int u,v; } edg[N]; void init() { memset(vis,0,sizeof(vis)); memset(out,0,sizeof(out)); memset(in,0,sizeof(in)); for(int i=0; i<26; i++)pre[i]=i; } int Find(int x) { if(pre[x] != x) pre[x] = Find(pre[x]); return pre[x]; } void Union(int x,int y) { x = Find(x); y = Find(y); if(x == y) return; pre[y] = x; } bool beconnect() //用並查集判斷這個圖是否聯通 { for(int i=0; i<n; i++) { int u=edg[i].u,v=edg[i].v; if(u!=v&&Find(u)!=Find(v))Union(u,v); } int f=-1,k; for(k=0; k<26; k++) { if(!vis[k])continue; if(f==-1)f=k; else if(Find(k)!=Find(f))break; } if(k<26)return false; return true; } int main() { int t; scanf("%d",&t); while(t--) { init(); scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%s",str); int u=str[0]-'a',v=str[strlen(str)-1]-'a'; edg[i].u=u; edg[i].v=v; vis[u]=vis[v]=1; out[u]++; in[v]++; } bool flag=true; int cnt1=0,cnt2=0; for(int i=0; i<26; i++) { if(!vis[i])continue; if(abs(out[i]-in[i])>1) { flag=false; break; } if(out[i]-in[i]==1) { cnt1++; if(cnt1>1) { flag=false; break; } } if(out[i]-in[i]==-1) { cnt2++; if(cnt2>1) { flag=false; break; } } } if(!((cnt1==1&&cnt2==1)||(cnt1==0&&cnt2==0)))flag=false; if(!beconnect())flag=false; if(flag)puts("Ordering is possible."); else puts("The door cannot be opened."); } return 0; }