日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

POJ2337 欧拉路径字典序输出

發布時間:2025/6/17 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 POJ2337 欧拉路径字典序输出 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ? 給一些單詞,問是否可以每個單詞只用一次,然后連接在一起(不一定要成環,能連接在一起就行)。


思路:
? ? ? 這個題目的入手點比較好想,其實就是問歐拉路徑,先說下解題步驟,然后在細說
(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 欧拉路径字典序输出的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。