1. 程式人生 > 其它 >CF508D(有向圖尤拉路徑)

CF508D(有向圖尤拉路徑)

傳送門:Problem - D - Codeforces

簡要題意:$n$ 個由三個字元組成的字串,要求利用相同前後綴拼接成長度為 $n + 2$ 的字串,問是否可行。

分析:模擬賽的一道題,賽時想到使用尤拉路徑解法,對於每個字串的前後綴轉化成雜湊並連邊,形成一張有向圖。如果無尤拉路徑存在,則一定不能完成題目要求。如果跑出了尤拉路徑,但總點數沒有達到 $n+2$,也同樣不符合題目中的要求。基本操作,鏈式前向星存邊,直接刪邊跑尤拉路徑即可(並不如其它題解所講會 TLE),時間複雜度 $O(n + m)$ ($m$ 指邊數)。

 1 #include<bits/stdc++.h>
 2
using namespace std; 3 const int N = 200010,M = 7010; 4 int n,cnt,jsq,tot = 1,len,start; 5 char a,b,c; 6 char path[N]; 7 int rd[M],cd[M]; 8 int ver[200010],Next[200010],head[200010]; 9 int turn(char op) 10 { 11 if(op >= '0' and op <= '9') return op - '0' + 1; 12 if(op >= 'A' and op <= 'Z') return
op - 'A' + 11; 13 if(op >= 'a' and op <= 'z') return op - 'a' + 37; 14 return 0; 15 } 16 char arcturn(int pos) 17 { 18 if(pos <= 10) return '0' + pos - 1; 19 if(pos <= 36) return 'A' + pos - 11; 20 return 'a' + pos - 37; 21 } 22 void add(int x,int y) 23 { 24 ver[++tot] = y,Next[tot] = head[x],head[x] = tot;
25 } 26 void dfs(int u) 27 { 28 int i; 29 while(head[u]) 30 { 31 i = head[u]; 32 head[u] = Next[i]; 33 dfs(ver[i]); 34 } 35 path[++len] = arcturn(u % 100); 36 } 37 signed main() 38 { 39 scanf("%d",&n); 40 for(int i = 1;i <= n;i++) 41 { 42 cin >> a >> b >> c; 43 int u = turn(a) * 100 + turn(b),v = turn(b) * 100 + turn(c); 44 cd[u]++,rd[v]++; 45 add(u,v); 46 start = u; 47 } 48 for(int i = 1;i <= 6262;i++) 49 { 50 int diff = rd[i] - cd[i]; 51 if(diff == -1) cnt++,start = i; 52 else if(diff == 1) jsq++; 53 else if(diff != 0) 54 { 55 printf("NO\n"); 56 return 0; 57 } 58 } 59 if(cnt > 1 || jsq > 1 || jsq + cnt == 1) 60 { 61 printf("NO\n"); 62 return 0; 63 } 64 dfs(start); 65 path[++len] = arcturn(start / 100); 66 if(len != n + 2) 67 { 68 printf("NO\n"); 69 return 0; 70 } 71 printf("YES\n"); 72 for(int i = len;i >= 1;i--) cout << path[i]; 73 printf("\n"); 74 return 0; 75 }
View Code