Codeforces Round #290 (Div. 2)C - Fox And Names——拓扑排序

http://codeforces.com/contest/510/problem/C

给你n个字符串,求是否存在按所给的字符串的顺序能够得到一个新的a-z的顺序表

拓扑排序
注意点:上下相邻两个串,如果上面的串是下面的串的前缀,则无需重新排列,反之如果下面的串是上面的串的前缀,则输出impossible。否则,就对相邻两个串最左边第一个不相同的字母之间连一条有向边

输出合法的a-z的序列

#include<bits/stdc++.h>
using namespace std;
int n;
char s[110][110];
int g[26][26];
int topo[26],t;
int vis[26];
bool dfs(int u){
    vis[u]=-1;
    for(int v=0;v<26;++v){
        if(g[u][v]){
            if(vis[v]<0) return false;
            else if(!vis[v]&&!dfs(v)) return false;
        }
    }
    vis[u]=1;
    topo[--t]=u;
    return true;
}
bool toposort(){
    t=26;
    for(int i=25;i>=0;--i){
        if(!vis[i]) if(!dfs(i)) return false;
    }
    return true;
}
int main()
{
    cin>>n;
    for(int i=0;i<n;++i)scanf("%s",s[i]);
    for(int i=0;i<n-1;++i){
        int l1=strlen(s[i]),l2=strlen(s[i+1]);
        int p=0;
        while(p<min(l1,l2)&&s[i][p]==s[i+1][p]) p++;
        if(p==l1&&l1<l2) continue;
        if(p==l2&&l2<l1){puts("Impossible");return 0;}
        if(g[s[i][p]-'a'][s[i+1][p]-'a'])continue;
        g[s[i][p]-'a'][s[i+1][p]-'a']=1;
    }
    if(toposort()){
        for(int i=0;i<26;++i) printf("%c",topo[i]+'a');
        puts("");
    }else puts("Impossible");
    return 0;
}

你可能感兴趣的:(编程语言)