牛客多校第五场 H subsequence 2 拓扑排序
题意:
给你长度最长为1000的字符串,这个字符串中最多有10种字母,每次给你两种字母,输出这两种字母在字符串中的相对位置,问你这个字符串原本是什么样子,如果不存在则输出-1
题解:
把整个字符串看作集合,每一个字符看作一个集合中的元素,字符串的前后关系看作偏序关系,作出这个集合的哈斯图,在哈斯图上拓扑排序。如果在拓扑到某点时发现没有入度为0的点了,那就输出-1;
#include<bits/stdc++.h> using namespace std; char ch[20]; int n,m,len[202],st[202]; char ss[200][20002],ans[20002]; int pos[20][202],cnt[20]; bool check(int u) { for(int i=1;i<m;i++) { int id=pos[u][i]; if(st[id]>len[id]||ss[id][st[id]]!=u+'a')return false; } return true; } void work(int u) { for(int i=1;i<m;i++) { int id=pos[u][i]; st[id]++; } } int main() { cin>>n>>m; for(int i=1;i<=m*(m-1)/2;i++) { scanf("%s",ch); int c=ch[0]-'a',d=ch[1]-'a'; pos[c][++cnt[c]]=i; pos[d][++cnt[d]]=i; cin>>len[i],st[i]=1; if(len[i])scanf("%s",ss[i]+1); } for(int i=1;i<=n;i++) { int t=-1; for(int j=0;j<m;j++)if(check(j)){t=j;break;} if(t==-1){puts("-1");return 0;} ans[i]=t+'a'; work(t); } for(int i=1;i<=m*(m-1)/2;i++)if(st[i]<=len[i]){puts("-1");return 0;} cout<<ans+1<<endl; }