POJ1270 Following Orders[拓扑排序所有方案 Kahn]

Following Orders

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 4885   Accepted: 1973

Description

Order is an important concept in mathematics and in computer science. For example, Zorn‘s Lemma states: ``a partially ordered set in which every chain has an upper bound contains a maximal element.‘‘ Order is also important in reasoning about the fix-point semantics of programs.

This problem involves neither Zorn‘s Lemma nor fix-point semantics, but does involve order. 
Given a list of variable constraints of the form x < y, you are to write a program that prints all orderings of the variables that are consistent with the constraints.

For example, given the constraints x < y and x < z there are two orderings of the variables x, y, and z that are consistent with these constraints: x y z and x z y.

Input

The input consists of a sequence of constraint specifications. A specification consists of two lines: a list of variables on one line followed by a list of contraints on the next line. A constraint is given by a pair of variables, where x y indicates that x < y.

All variables are single character, lower-case letters. There will be at least two variables, and no more than 20 variables in a specification. There will be at least one constraint, and no more than 50 constraints in a specification. There will be at least one, and no more than 300 orderings consistent with the contraints in a specification.

Input is terminated by end-of-file.

Output

For each constraint specification, all orderings consistent with the constraints should be printed. Orderings are printed in lexicographical (alphabetical) order, one per line.

Output for different constraint specifications is separated by a blank line.

Sample Input

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

Sample Output

abfg
abgf
agbf
gabf

wxzvy
wzxvy
xwzvy
xzwvy
zwxvy
zxwvy

Source

Duke Internet Programming Contest 1993,uva 124

--------------------------------------

所有方案,需要回溯,用Kahn比较好

L← Empty list that will contain the sorted elements
S ← Set of all nodes with no incoming edges
while S is non-empty do
    remove a node n from S
    insert n into L
    foreach node m with an edge e from nto m do
        remove edge e from thegraph
        ifm has no other incoming edges then
            insert m into S
if graph has edges then
    return error (graph has at least onecycle)
else
    return L (a topologically sortedorder)

就是找入度为0的点(最好用个stack,循环的话复杂的太高),加入topo头部

感觉比dfs好,复杂度都是O(V+E)

本题回溯所有方案,复杂度乘上一个V;V很小,不用stack也可以;用个id比较方便吧

字符读入太坑人.........

//
// main.cpp
// poj1270
//
// Created by Candy on 9/11/16.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=30,M=55;
char s[105];
int a[N],num=0,n=0,id[N];
int ch[N][N],topo[N],ind[N];

void print(){
    for(int i=1;i<=n;i++) printf("%c",(char)topo[i]+‘a‘-1);
    printf("\n");
}
void dfs(int d){ //printf("dfs %d\n",d);
    if(d==n+1){print();return;}
    for(int i=1;i<=n;i++)
        if(ind[i]==0){
            ind[i]--; topo[d]=a[i];
            for(int j=1;j<=ch[i][0];j++) ind[ch[i][j]]--;
            dfs(d+1);
            for(int j=1;j<=ch[i][0];j++) ind[ch[i][j]]++;
            ind[i]++;
        }
}
int main(int argc, const char * argv[]) {
    while(fgets(s,105,stdin)){ //printf("p %s\n",s);
        n=0;
        memset(topo,0,sizeof(topo));
        memset(ch,0,sizeof(ch));
        memset(ind,0,sizeof(ind));
        int len=strlen(s); //printf("len %d\n",len);
        for(int i=0;i<len;i++)
            if(s[i]>=‘a‘&&s[i]<=‘z‘) a[++n]=s[i]-‘a‘+1;
        sort(a+1,a+1+n);
        for(int i=1;i<=n;i++) id[a[i]]=i;

        fgets(s,105,stdin);
        len=strlen(s);
        int last=0;
        for(int i=0;i<=len;i++)
            if(s[i]>=‘a‘&&s[i]<=‘z‘){
                int t=s[i]-‘a‘+1;
                t=id[t];
                if(last==0) last=t;
                else{ch[last][++ch[last][0]]=t;ind[t]++;last=0;}
            }
        dfs(1);
        printf("\n");
    }
    return 0;
}
时间: 2024-10-19 08:13:29

POJ1270 Following Orders[拓扑排序所有方案 Kahn]的相关文章

poj 1270 Following Orders(拓扑排序+dfs)

大致题意:每个样例包含两行,第一行输入n个字符,可能是无序的.第二行输入成对的a b,代表a要在b前面.输出所有的符合这样的序列. 思路:很明显的拓扑排序.要输出所有的序列,那么就从入度为0的点进行dfs,每次选择一个入度为0的点,加入输出序列并把与它相邻的点的入度减一.dfs结束后要把状态再改回来. #include <stdio.h> #include <algorithm> #include <set> #include <map> #include

UVA 124 &amp; POJ 1270 Following Orders(拓扑排序)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=60 http://poj.org/problem?id=1270 Following Orders Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3806   Accepted: 1507 Description Or

POJ 1270 Following Orders 拓扑排序全输出

Description Order is an important concept in mathematics and in computer science. For example, Zorn's Lemma states: ``a partially ordered set in which every chain has an upper bound contains a maximal element.'' Order is also important in reasoning a

【每日算法】图算法(遍历&amp;MST&amp;最短路径&amp;拓扑排序)

图有邻接矩阵和邻接表两种存储方法,邻接矩阵很简单,这里不讨论,下面我们先看看常用的邻接表表示方法. 邻接表常用表示方法 指针表示法 指针表示法一共需要两个结构体: struct ArcNode //定义边表结点 { int adjvex: //邻接点域 ArcNode* next; }; struct VertexNode //定义顶点表结点 { int vertex; ArcNode* firstedge; }; 每个节点对应一个VertexNode,其firstedge指向边表(与当前节点邻

图论排序---拓扑排序

定义 对于有向无权无环图,进行拓扑排序 实现方式 Kahn算法 基于DFS的拓扑排序算法 Kahn算法 优化前时间复杂度O(\(n^{2}\)) 排序的过程 1.对于DAG,先输出没有前驱的点 2.把与前驱相关的边删除 3.继续输出没有前驱的点 4.重复前者,直到DAG为空或者没有前驱 如果我们有如下的一个有向无环图,我们需要对这个图的顶点进行拓扑排序,过程如下: 首先,我们发现V6和v1是没有前驱的,所以我们就随机选去一个输出,我们先输出V6,删除和V6有关的边,得到如下图结果: 然后,我们继

POJ1270 Following Orders (拓扑排序)

Following Orders Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4254   Accepted: 1709 Description Order is an important concept in mathematics and in computer science. For example, Zorn's Lemma states: ``a partially ordered set in which

poj1270拓扑排序

题意:给定一些大小关系,把关系从大到小排序,如果有多种相同关系就按字典序排序.例如 x < y && x < z 则满足关系的有xyz 和 xzy . 思路:我们可以把每组大小关系建一条有向边,这样就形成了一个有向图,再对有向图进行拓扑,得到的结果即满足.但是拓扑出来的是一组可行解,而题意是要输出所有可行解,刚好可以想到递归求拓扑时可以回溯:那样就可以把所有的可行解输出.不过要把所有的变量排序. 代码: #pragma warning (disable: 4786) #incl

poj1270Following Orders(拓扑排序+dfs回溯)

题目链接: 啊哈哈,点我点我 题意是: 第一列给出所有的字母数,第二列给出一些先后顺序.然后按字典序最小的方式输出所有的可能性... 思路: 总体来说是拓扑排序,但是又很多细节要考虑,首先要按字典序最小的方式输出,所以自然输入后要对这些字母进行排列,然后就是输入了,用scanf不能读空格,所以怎么建图呢??设置一个变量判断读入的先后顺序,那么建图完毕后,就拓扑排序了,那么多种方式自然就是dfs回溯了..那么这个问题就得到了解决.. 题目: Following Orders Time Limit:

【Vj作业】【拓扑排序经典理解题】Ordering Tasks 1、Kahn算法;2、基于DFS的算法。

2018-02-13 链接   https://cn.vjudge.net/contest/211129#problem/D John has n tasks to do. Unfortunately, the tasks are not independent and the execution of one task is only possible if other tasks have already been executed.InputThe input will consist o