CF508D(有向图欧拉路径)
简要题意:$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 }

浙公网安备 33010602011771号