牛客多校第五场 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;
}

猜你喜欢

转载自www.cnblogs.com/isakovsky/p/11290897.html