nyoj99(欧拉路)
生活随笔
收集整理的這篇文章主要介紹了
nyoj99(欧拉路)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
http://acm.nyist.net/JudgeOnline/problem.php?pid=99
TLE: 首先建立一個Trie樹,然后利用dfs貪心地去尋找可以拼接的單詞。在dfs中,由于每次都是從最小的字母開始找起,所以只要能夠找到就一定保證是字典序最小的。。。可惜超時了。。其實仔細想想也是的,每一個節點都要循環26次。
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> using namespace std;const int maxn = 1000; struct Node {int id,back;Node *next[26]; }; int n,cnt,ans[maxn]; char str[1010][30]; bool vis[maxn]; Node *T;void build(char *s) {int len = strlen(s);Node *p = T;for(int i = 0; i < len; i++){if(p->next[s[i]-'a'] == NULL){p->next[s[i]-'a'] = (Node *)malloc(sizeof(Node));p->next[s[i]-'a']->id = p->next[s[i]-'a']->back = 0;for(int j = 0; j < 26; j++)p->next[s[i]-'a']->next[j] = NULL;}p = p->next[s[i]-'a'];}p->id = ++cnt; p->back = s[len-1] - 'a'; }bool dfs(Node *root,int num) {if(root == NULL) return false;if(root->id > 0 && vis[root->id] == false){ans[num] = root->id;if(num == n) return true;vis[root->id] = true;if(dfs(T->next[root->back],num+1)) return true;vis[root->id] = false;return false;}for(int i = 0; i < 26; i++){if(root->next[i] == NULL) continue;if(dfs(root->next[i],num)) return true;}return false; }int main() { int t;scanf("%d",&t);while(t--){T = (Node *)malloc(sizeof(Node));T->id = T->back = 0; for(int i = 0; i < 26; i++) T->next[i] = NULL;cnt = 0;scanf("%d",&n);for(int i = 1; i <= n; i++){getchar();scanf("%s",str[i]);build(str[i]);}memset(vis,false,sizeof(vis));if(dfs(T,1)){for(int i = 1; i <= n; i++)if(i == 1)printf("%s",str[ans[i]]);else printf(".%s",str[ans[i]]);}else printf("***");printf("\n");}return 0; }AC(copy別人的):以字母為節點的有向圖的歐拉路徑,有向圖的歐拉路徑的充要條件是所有節點的入度等于出度,或者有一個節點的入度比出度小1,同時有一個節點的入度比出度大1。當然首先這個圖得是連通的,后面會通過DFS來判斷。
首先通過入度出度的條件判斷能否形成歐拉路徑。
若能形成,則讓入度比出度小1的節點作為起始點(若沒有這樣的節點,就按字典順序選第1個出現的字母作為起始點),進行dfs,找到滿足條件的路徑,若dfs找不到,那說明該圖還是連通圖
總結
以上是生活随笔為你收集整理的nyoj99(欧拉路)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java Class的热替换 自定义Cl
- 下一篇: JEECG Framework 3.5.