2019牛客暑期多校训练营(第五场)H subsequence 2(拓扑排序)
题目链接:https://ac.nowcoder.com/acm/contest/885/H
题目大意:
给定n,m,表示原字符串长度为n,以及m*(m-1)/2个数据,每个数据第一行是两个小写字母和原字符串中包含这两个字母的总长度,第二行是按原字符串两个字母的顺序输出,让你求原字符串n,无则输出-1。
解题报告:
对题目给的字符进行编号,以及编号过的字符则无需再编,对相邻的两个字符建边,最后按拓扑序输出。
AC代码:
1 #include<vector> 2 #include<cstdio> 3 #include<iostream> 4 #include<cmath> 5 #include<queue> 6 #include<stack> 7 #include<cmath> 8 #include<algorithm> 9 #include<string> 10 #include<cstring> 11 #include<cstdlib> 12 #define numm ch-48 13 #define pd putchar(' ') 14 #define pn putchar('\n') 15 #define pb push_back 16 #define fi first 17 #define se second 18 #define fre1 freopen("1.txt","r",stdin) 19 #define fre2 freopen("2.txt","w",stdout) 20 using namespace std; 21 template <typename T> 22 void read(T &res) { 23 bool flag=false;char ch; 24 while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true); 25 for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm); 26 flag&&(res=-res); 27 } 28 template <typename T> 29 void write(T x) { 30 if(x<0) putchar('-'),x=-x; 31 if(x>9) write(x/10); 32 putchar(x%10+'0'); 33 } 34 const int maxn=1e5+7; 35 const int N=60; 36 const int inf=0x3f3f3f3f; 37 const int INF=0x7fffffff; 38 const int mod=998244353; 39 typedef long long ll; 40 struct wtz { 41 int v,net; 42 }wtz[maxn<<1]; 43 vector<int>mp[30]; 44 int num[maxn]; 45 char s1[10],s2[maxn]; 46 int t[30],sum,in[maxn],head[maxn]; 47 void add(int u,int v) { 48 wtz[++sum].v=v; 49 wtz[sum].net=head[u]; 50 head[u]=sum; 51 } 52 int main() 53 { 54 int _,m,n; 55 read(n),read(m); 56 memset(head,-1,sizeof(head)); 57 int cnt=0; 58 for(int z=1;z<=m*(m-1)/2;z++) { 59 60 int len1,len2,lst=-1; 61 scanf(" %s",s1); 62 cin>>len2; 63 if(!len2) continue; 64 memset(t,0,sizeof(t)); 65 scanf("%s",s2); 66 for(int i=0;i<len2;i++) { ///给字符标号 67 int k=s2[i]-'a'; 68 t[k]++; 69 if(mp[k].size()<t[k]) { 70 mp[k].pb(++cnt); 71 num[cnt]=k; 72 } 73 if(lst!=-1) add(lst,mp[k][t[k]-1]),in[mp[k][t[k]-1]]++; 74 lst=mp[k][t[k]-1]; 75 } 76 if(cnt>n) 77 return write(-1),pn,0; 78 } 79 if(cnt<n) 80 return write(-1),pn,0; 81 queue<int> que; ///拓扑排序 82 vector<int> ans; 83 for(int i=1;i<=n;i++) 84 if(!in[i]) que.push(i); 85 86 while(!que.empty()) { 87 int k=que.front(); 88 que.pop(); 89 ans.pb(k); 90 for(int i=head[k]; ~i ; i=wtz[i].net ) { 91 --in[wtz[i].v]; 92 if(!in[wtz[i].v]) 93 que.push(wtz[i].v); 94 } 95 } 96 97 if(ans.size()!=n) return write(-1),pn,0; 98 for(int i=0;i<n;i++) 99 putchar('a'+num[ans[i]]);pn; 100 return 0; 101 }
所谓人生,一半惊喜,一半遗憾