poj1270拓扑排序

题意:给定一些大小关系,把关系从大到小排序,如果有多种相同关系就按字典序排序。例如 x < y && x < z 则满足关系的有xyz 和 xzy 。

思路:我们可以把每组大小关系建一条有向边,这样就形成了一个有向图,再对有向图进行拓扑,得到的结果即满足。但是拓扑出来的是一组可行解,而题意是要输出所有可行解,刚好可以想到递归求拓扑时可以回溯;那样就可以把所有的可行解输出。不过要把所有的变量排序。

代码:

#pragma warning (disable: 4786)
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
const int maxn = 200;
char var[maxn];
char ans[maxn];
char st[maxn];
int map[maxn][maxn];
int n;
int indeg[maxn];
std::map<char,int>hash;

void toposort(int k) //拓扑回溯
{
    if(k == n)
    {
        ans[n] = '';
        printf("%s
",ans);
        return ;
    }
    for(int i=0; i< n; i++)
    {
        int j;
        if(indeg[i] == 0)
        {
            indeg[i] -- ;
            ans[k] = st[i];
            for(j =0;j < n;j++)
            {
                if(map[i][j]) indeg[j] --;
            }
            toposort(k+1);
            indeg[i] ++;
            for(j=0;j<n;j++)
                if(map[i][j]) indeg[j] ++;
        }
    }
}

void init()
{
    n = 0;
    memset(indeg,0,sizeof(indeg));
    memset(map,0,sizeof(map));
}

void work()
{
    char c[3];
    int i;
    int l = strlen(var),k =0;
    init();
    for( i =0;i<l;i++)
    {
        if(var[i] >= 'a' && var[i] <= 'z')
            st[n++] = var[i];
    }
    std::sort(st,st+n);
    for(i=0;i<n;i++)
    {
        hash[st[i]] = i;
    }

    gets(var);
    l = strlen(var);
    for( i=0; i<l; i++)
    {
        if(var[i] >= 'a' && var[i] <= 'z')
        {
            c[k%2] = var[i];
            if(k % 2 == 1)
            {
                map[hash[c[0]]][hash[c[1]]] = 1;
                indeg[hash[c[1]]] ++;
            }
            k++;
        }
    }    
    toposort(0);
    printf("
");
}

int main()
{
    while(gets(var))
    {        
        work();
    }
    return 0;
}


/*

a b f g
a b b f
v w x y z
v y x v z v w v

  */
原文地址:https://www.cnblogs.com/BruceNoOne/p/3885687.html