UVA10129-歐拉回路-DFS
阿新 • • 發佈:2018-12-19
第一次寫部落格,以前一直沒有總結過,現在開始對自己學的東西做一些記錄吧,方便以後複習或者就當作留個腳印。
筆者目前大一,水平弱弱弱…有不正確的地方或者可以改進的地方還望指出。
找夥伴,有想一起學習的朋友可以一起交流交流。email: [email protected]
題目大意:輸入n個單詞,判斷是否能把所有單詞連線成一個串,使得每個單詞首字母與前一個單詞尾字母相同。
思路:
1:把每個單詞看作一座橋,二十六給英文字母看作節點,儲存有向圖。
2:判斷整個有向圖的奇點數是否大於2,大於2則不存在尤拉道路,存在則走第三步。
3:判斷圖的連通性,筆者目前只會用DFS(並查集還沒學),
注意:
思路講起來簡潔,然而每次實現都會遇到各種問題。(筆者太弱了)
若奇點數為2,判斷連通性的時候一定要是注意起點是出度大於入度的那個節點。
若奇點數為0,(容易忽略)一定要找一個存在橋的節點。
程式碼:
話不多說,直接上AC程式碼。看了下各路大神的程式碼,都這麼短!!!都不好意思貼上來了。
不太想寫註釋了,程式碼如下。
#include<iostream> #include<string> #include<cstring> #include<cstdlib> using namespace std; bool G[26][26]; int out_cnt[26],in_cnt[26]; void dfs(int in) { for(int i=0;i<26;++i) { if(G[in][i]) { G[in][i]=G[i][in]=false; dfs(i); } } } bool is_cncted(int in) { dfs(in); for(int i=0;i<26;++i) for(int j=0;j<26;++j) if(G[i][j]) return false; return true; } int main() { int n; cin>>n; while(n--) { memset(G,0,sizeof(G)); memset(out_cnt,0,sizeof(out_cnt)); memset(in_cnt,0,sizeof(in_cnt)); int t; cin>>t; string s; while(t--) { cin>>s; G[*s.begin()-'a'][*(s.end()-1)-'a']=1; out_cnt[*s.begin()-'a']++; in_cnt[*(s.end()-1)-'a']++; } int sp_in=0,sp_cnt=0,flag=1; for(int i=0;i<26;++i) { if(in_cnt[i]!=out_cnt[i]) { if(++sp_cnt>2||abs(in_cnt[i]-out_cnt[i])!=1) { flag=0; break; } if(sp_cnt==1) sp_in=i; else { if(in_cnt[sp_in]-out_cnt[sp_in]+in_cnt[i]-out_cnt[i]) { flag=0; break; } if(out_cnt[sp_in]<in_cnt[sp_in]) { sp_in=i; } } } } if(flag) { if(!out_cnt[sp_in]) for(int i=0;i<26;++i) if(out_cnt[i]) { sp_in=i; break; } if(!is_cncted(sp_in)) flag=0; } if(flag) cout<<"Ordering is possible."<<endl; else cout<<"The door cannot be opened."<<endl; } return 0; }