[Codeforces#510C] Fox And Names

Posted qixingzhi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Codeforces#510C] Fox And Names相关的知识,希望对你有一定的参考价值。

Codeforces题号:#510C

出处: Codeforces

主要算法:判环+拓扑

难度:4.2

思路分析:

       要是把这道题联系到图上就很容易想了。

  如何建图?由于最后要求名字满足字典序,所以不妨以字母为节点,然后按照题意的顺序从小的到大的连边。建图了又什么用?如果图存在环,那么也就意味着矛盾了——因为这比自己小的节点比自己大。因此是否存在一个合法的字典序的判断依据就是建的图是否存在环。

  第二步,如何输出任意一个方案?这很简单,由于有可能有的字母根本没有参与建图,所以这些字母就不需要管了。对于在图里的字母,入度为0的点就是已知的应当最小的点——所以我们进行一次拓扑排序来得到序列。最后和其它字母拼合起来就好了。

代码注意点:

  注意有两个相同前缀的字符串时,如果前面的那个字符串比后面的还要长,那么一定不满足,直接输出impossible就好了。因为无论字典序如何,都不可能满足前面的字典序比后面的小。

Code

 

/** This Program is written by QiXingZhi **/
#include <cstdio>
#include <queue>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define  r  read()
#define  Max(a,b)  (((a)>(b)) ? (a) : (b))
#define  Min(a,b)  (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int N = 1010;
const int INF = 1061109567;
inline int read(){
    int x = 0; int w = 1; register int c = getchar();
    while(c ^ - && (c < 0 || c > 9)) c = getchar();
    if(c == -) w = -1, c = getchar();
    while(c >= 0 && c <= 9) x = (x << 3) +(x << 1) + c - 0, c = getchar();
    return x * w;
}
string s[N];
queue <int> q;
vector <int> G[3000];
bool exist[N],vis[N],b[N],hh[N];
int rd[N],Q[N],ans_topo[N];
int n,len1,len2,flg,_cur,t,topo_num;
inline void AddEdge(int u, int v){
    exist[u] = 1;
    exist[v] = 1;
    G[u].push_back(v);
    ++rd[v];
}
inline void ThrowOut(){
    printf("Impossible");
    exit(0);
}
inline bool BFS(int x){
    while(!q.empty()) q.pop();
    q.push(x);
    int cur,sz,to;
    while(!q.empty()){
        cur = q.front();
        q.pop();
        if(cur == _cur){
            if(flg == -1){
                ++flg;
            }
            else if(flg == 0){
                return 1;
            }
        }
        if(vis[cur]) continue;
        vis[cur] = 1;
        sz = G[cur].size();
        for(int i = 0; i < sz; ++i){
            to = G[cur][i];
            q.push(to);
        }
    }
    return 0;
}
inline bool Check_Circle(){
    for(int i = a; i <= z; ++i){
        memset(vis,0,sizeof(vis));
        if(exist[i]){
            _cur = i;
            flg = -1;
            if(BFS(_cur)) return 1;
        }
    }
    return 0;
}
int main(){
//    freopen(".in","r",stdin);
    cin >> n;
    for(int i = 1; i <= n; ++i){
        cin >> s[i];
    }
    for(int i = 2; i <= n; ++i){
        len1 = s[i-1].size();
        len2 = s[i].size();
        flg = 0;
        for(int j = 0; j < len2; ++j){
            if(j >= len1){
                flg = 1;
                break;
            }
            if(s[i-1][j] != s[i][j]){
                flg = 1;
                AddEdge(s[i-1][j],s[i][j]);
                break;
            }
        }
        if(flg == 0 && len1 > len2){
            ThrowOut();
        }
    }
    if(Check_Circle() == 1){
        ThrowOut();
    }
    int flg=0,sz;
    for(;;){
        flg = 0, t = 0;
        for(int i = a; i <= z; ++i){
            if(rd[i] == 0 && !b[i] && exist[i]){
                flg = 1;
                b[i] = 1;
                Q[++t] = i;
            }  
        }
        if(!flg) break;
        for(int i = 1; i <= t; ++i){
            int cur = Q[i];
            ans_topo[++topo_num] = cur;
            hh[cur] = 1;
            sz = G[cur].size();
            for(int j = 0; j < sz; ++j){
                --rd[G[cur][j]];
            }
        }
    }
    for(int i = 1; i <= topo_num; ++i){
        printf("%c",ans_topo[i]);
    }
    for(int i = a; i <= z; ++i){
        if(!hh[i]){
            printf("%c",i);
        }
    }
    return 0;
}

 

以上是关于[Codeforces#510C] Fox And Names的主要内容,如果未能解决你的问题,请参考以下文章

codeforce 510C Fox And Names

Fox And Names CodeForces - 510C

CF510E. Fox And Dinner

Codeforces Round #290 (Div. 2) B. Fox And Two Dots(DFS)

cf510 D. Fox And Jumping(dp)

CF510B Fox And Two Dots(搜索图形环)