POJ2337 欧拉路径字典序输出
生活随笔
收集整理的這篇文章主要介紹了
POJ2337 欧拉路径字典序输出
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給一些單詞,問是否可以每個單詞只用一次,然后連接在一起(不一定要成環,能連接在一起就行)。
思路:
? ? ? 這個題目的入手點比較好想,其實就是問歐拉路徑,先說下解題步驟,然后在細說
(1) 把每個單詞看成一條邊,單詞的首字母和尾字母是點
(2) 然后記錄入度,出度,根據入度出度判斷是不是歐拉路徑或者回路
(3) 別往了判斷所有點是不是屬于同一個連通子集,這個可以用并查集啥的
(4) 把所有的邊都排序下,至于是什么順序,根據自己的存圖方式去排
(5) 歐拉路徑就從頭開始(要是歐拉回路就找個最小的點)深搜找出路徑
? ? ? 給一些單詞,問是否可以每個單詞只用一次,然后連接在一起(不一定要成環,能連接在一起就行)。
思路:
? ? ? 這個題目的入手點比較好想,其實就是問歐拉路徑,先說下解題步驟,然后在細說
(1) 把每個單詞看成一條邊,單詞的首字母和尾字母是點
(2) 然后記錄入度,出度,根據入度出度判斷是不是歐拉路徑或者回路
(3) 別往了判斷所有點是不是屬于同一個連通子集,這個可以用并查集啥的
(4) 把所有的邊都排序下,至于是什么順序,根據自己的存圖方式去排
(5) 歐拉路徑就從頭開始(要是歐拉回路就找個最小的點)深搜找出路徑
? ? ?之前也沒寫過輸出歐拉路徑啥的啊!看有人說可以用棧遞歸存邊,然后就在紙上畫了幾個8想想,覺得有道理,就自己寫了一個歐拉路的(其實很簡單),至于排序的地方,我想的是直接在存邊之前先把邊排序下,因為歐拉路徑輸出的時候也是比較簡單“畫6的感覺”,要求字典序最小,因為我用的是前向星,其實這個東西建邊是倒敘的,就是a-b a-c a-d 的順序進去,那么訪問的時候是a-d,a-c,a-b這樣的,全都是抱著試一試,結果直接a了。雖然是簡單題,但是挺高興啊。
#include<stack> #include<stdio.h> #include<string.h> #include<algorithm>#define N_node 30 #define N_edge 1000 + 100using namespace std;typedef struct {int to ,next; }STAR;typedef struct {char str[30]; }EDGE;STAR E[N_edge]; EDGE edge[N_edge]; int list[N_node] ,tot; int mer[N_node]; int mark[N_edge]; int deg[N_node]; stack<int>mysk;bool camp(EDGE a ,EDGE b) {return strcmp(a.str ,b.str) > 0; }void add(int a ,int b) {E[++tot].to = b;E[tot].next = list[a];list[a] = tot; }int finds(int x) {return x == mer[x] ? x : mer[x] = finds(mer[x]); }void DFS(int s) {for(int k = list[s] ;k ;k = E[k].next){if(mark[k]) continue;mark[k] = 1;DFS(E[k].to);mysk.push(k);} }int main () {int t ,n ,i ,j;int mkc[30];scanf("%d" ,&t);while(t--){scanf("%d" ,&n);memset(deg ,0 ,sizeof(deg));memset(mkc ,0 ,sizeof(mkc));for(i = 1 ;i <= 26 ;i ++)mer[i] = i;for(i = 1 ;i <= n ;i ++){scanf("%s" ,edge[i].str);int a = edge[i].str[0] - 'a' + 1;int b = edge[i].str[strlen(edge[i].str)-1] - 'a' + 1;mer[finds(a)] = finds(b);mkc[a] = mkc[b] = 1;deg[a] ++;deg[b] --;}int s = 0 ,z = 0 ,f = 0 ,min;for(i = 1 ;i <= 26 ;i ++){if(mkc[i]){if(mer[i] == i) s ++;if(!deg[i]) continue;if(deg[i] == 1)z ++ ,min = i;else if(deg[i] == -1) f ++;else s ++;}}if(s != 1 || f + z != 0 && f + z != 2){printf("***\n");continue;}sort(edge + 1 ,edge + n + 1 ,camp);memset(list ,0 ,sizeof(list));tot = 1;for(i = 1 ;i <= n ;i ++){int a = edge[i].str[0] - 'a' + 1;int b = edge[i].str[strlen(edge[i].str)-1] - 'a' + 1;add(a ,b);}if(z + f == 0) min = edge[n].str[0] - 'a' + 1;while(!mysk.empty())mysk.pop();memset(mark ,0 ,sizeof(mark));DFS(min);while(!mysk.empty()){int tou = mysk.top();mysk.pop();if(mysk.empty())printf("%s\n" ,edge[tou-1].str);else printf("%s." ,edge[tou-1].str);}}return 0; }
總結
以上是生活随笔為你收集整理的POJ2337 欧拉路径字典序输出的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ2118基础矩阵快速幂
- 下一篇: POJ2709 染料贪心