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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【POJ - 2337】Catenyms(欧拉图相关,欧拉通路输出路径,tricks)

發(fā)布時間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【POJ - 2337】Catenyms(欧拉图相关,欧拉通路输出路径,tricks) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題干:

A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms:?

dog.gophergopher.ratrat.tigeraloha.alohaarachnid.dog


A compound catenym is a sequence of three or more words separated by periods such that each adjacent pair of words forms a catenym. For example,?

aloha.aloha.arachnid.dog.gopher.rat.tiger?

Given a dictionary of lower case words, you are to find a compound catenym that contains each of the words exactly once.

Input

The first line of standard input contains t, the number of test cases. Each test case begins with 3 <= n <= 1000 - the number of words in the dictionary. n distinct dictionary words follow; each word is a string of between 1 and 20 lowercase letters on a line by itself.

Output

For each test case, output a line giving the lexicographically least compound catenym that contains each dictionary word exactly once. Output "***" if there is no solution.

Sample Input

2 6 aloha arachnid dog gopher rat tiger 3 oak maple elm

Sample Output

aloha.arachnid.dog.gopher.rat.tiger ***

題目大意:

? 給n個字符串,讓你串成一個串,要求輸出順序,如果多解要求字典序最小

解題報告:

? ?不用并查集判連通,用dfs判連通就行了。注意路徑記錄的時候要先dfs再回溯記錄,因為可能有這種情況。

所以你需要再倒回來路徑的時候記錄路徑,因為首先歐拉通路他只有一個終點(再也走不動的地方),你最后走不動了回溯的時候著一定是倒著回溯的,最后倒著輸出就行了。

再就是注意搜索的起點:

(1)如果發(fā)現(xiàn)所有節(jié)點的出度與入度都相等,那么有向圖中存在歐拉回路,當(dāng)然也一定存在歐拉通路了。這時以任一節(jié)點開始深搜一條路徑即可。(因為字典序要求最小我們就從出現(xiàn)的字符集中最小的那個字母開始搜)
(2)如果發(fā)現(xiàn)存在 out[i] - in[i] == 1 的節(jié)點,那么歐拉通路是以out[i] - in[i] == 1的那個 i 為始點的,以 in[i] - out[i] == 1 的那個 i 為終點。這時我們要以這個out[i] - in[i] == 1 的節(jié)點為起點開始深搜。

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define F first #define S second #define ll long long #define pb push_back #define pm make_pair using namespace std; typedef pair<string,int> PSI; const int MAX = 1000 + 5; string s[MAX]; int n; string ans[MAX]; int len[MAX],in[MAX],out[MAX],tot; bool vis[MAX]; vector<PSI> vv[129]; void dfs(char st) {int up = vv[st].size();for(int i = 0; i<up; i++) {PSI cur = vv[st][i];if(vis[cur.S]) continue;vis[cur.S] = 1; dfs(cur.F[len[cur.S]-1]); ans[++tot] = cur.F;} } int main() {int t;cin>>t;while(t--) {tot=0;scanf("%d",&n);for(int i = 1; i<=127; i++) in[i]=out[i]=0,vv[i].clear();for(int i = 1; i<=n; i++) {vis[i] = 0;cin>>s[i];len[i] = s[i].length();}char minn = 'z';for(int i = 1; i<=n; i++) { char st = s[i][0];char ed = s[i][len[i]-1];vv[st].pb(pm(s[i],i));in[ed]++;out[st]++;minn = min(minn,ed);minn = min(minn,st);}int flag = 1,ru=0,chu=0;for(int i = 'a'; i<='z'; i++) {sort(vv[i].begin(),vv[i].end());if(!in[i] && !out[i]) continue;if(in[i] == out[i]) continue;else if(in[i] - out[i] == 1) ru++;else if(out[i] - in[i] == 1) chu++,minn=i;else {flag = 0;break;}}if(flag == 0 || ru>1 || chu>1 || ru!=chu) puts("***");else {dfs(minn);if(tot != n) puts("***");else {for(int i = n; i>=1; i--) {if(i != n) printf(".");cout << ans[i];}puts("");}}} return 0 ; }

總結(jié):提問,如果要求輸出歐拉回路的路徑咋辦?答:在起點那里稍微判斷一下就行了。或者最后直接輸出起點。因為既然是歐拉回路的話可以以任何一個點為起點,所以你欽點的起點最后一定可以繞回來,所以最后輸出答案的時候先輸出一遍起點就可以。或者在dfs的時候稍微記錄一下起點。

總結(jié)

以上是生活随笔為你收集整理的【POJ - 2337】Catenyms(欧拉图相关,欧拉通路输出路径,tricks)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。