题意:第一行给出变量,第二行给出约束关系,要求按字典序输出全部拓扑序列
思路:全拓扑排序。
输入比较恶心,处理一下就可以了。
看见discuss上有人用dfs和全排列AC掉了,不得不佩服一下,这道题被我活生生做成了模版题。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#include <stack>
using namespace std;
typedef struct CsNode
{
int data;
bool vis;
CsNode *parent,*firstchild,*nextsibling;
} CsNode,*toptree;
int n;
int in[25];
char val[25];
void process(vector<int> gl[],stack<int> &sk,int p)
{
in[p]--;
for(int i=0; i<gl[p].size(); ++i)
in[gl[p][i]]--;
for(int i=0; i<n; ++i)
if(!in[i]) sk.push(i);
}
void addinagree(vector<int> gl[],int p)
{
in[p]++;
for(int i=0; i<gl[p].size(); ++i)
in[gl[p][i]]++;
}
void createtoptree(vector<int> gl[])
{
CsNode *head;
head=new CsNode;
head->data=head->vis=head->vis=head->parent=head->firstchild=head->nextsibling=NULL;
CsNode *T;
T=head;
stack<int> sk;
int cd[25]={0},cdlen=0;
for(int i=0; i<n; ++i)
if(!in[i]) sk.push(i);
CsNode *p;
while(!sk.empty())
{
while(!sk.empty())
{
while(!sk.empty())
{
int gettop=sk.top();
sk.pop();
p=new CsNode;
p->parent=T;
p->firstchild=NULL;
p->data=gettop;
p->vis=false;
p->nextsibling=T->firstchild;
if(p->nextsibling) p->nextsibling->parent=p;
T->firstchild=p;
}
T=T->firstchild;
int pos=T->data;
cd[cdlen++]=pos;
process(gl,sk,pos);
}
cd[cdlen]=-1;
int k=0;
while(cd[k]!=-1)
{
char c=val[cd[k]];
printf("%c",c);
k++;
}
printf("\n");
while((p->nextsibling==0||p->vis==true)&&p->parent!=0)
{
if(p->vis==false)
{
int pos=p->data;
addinagree(gl,pos);
cdlen--;
}
p->vis=false;
CsNode *q=p;
p=p->parent;
delete q;
}
if(p->nextsibling&&!p->vis)
{
p->vis=true;
int pos=p->data;
addinagree(gl,pos);
cdlen--;
T=p->nextsibling;
pos=T->data;
cd[cdlen++]=pos;
process(gl,sk,pos);
}
}
}
int main()
{
char t;
while(scanf("%c",&t)!=EOF)
{
vector<int> g[25];
memset(in,0,sizeof(in));
n=0;
if(islower(t)) val[n++]=t;
while(scanf("%c",&t)&&t!='\n')
if(islower(t)) val[n++]=t;
sort(val,val+n);
map<char ,int> mp;
for(int i=0; i<n; ++i)
mp[val[i]]=i;
int m=0;
char a,b;
while(scanf("%c",&t)&&t!='\n')
{
if(islower(t))
{
m++;
if(m%2==0&&m)
{
b=t;
int u=mp[a],v=mp[b];
if(g[u].end()==find(g[u].begin(),g[u].end(),v))
{
in[v]++;
g[u].push_back(v);
}
}
else
a=t;
}
}
createtoptree(g);
printf("\n");
}
return 0;
}
这是我后来自己写的dfs。POJ上AC了,但是UVa上WA了。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#define MAXN 32
using namespace std;
int n;
int in[MAXN];
int grid[MAXN][MAXN];
char lt[MAXN];
bool use[MAXN];
map<char,int> mp;
char ans[MAXN];
void dfs(int cur)
{
if(cur==n)
printf("%s\n",ans);
else
{
for(int i=0; i<n; ++i)
if(!in[i]&&!use[i])
{
use[i]=true;
for(int j=0; j<n; ++j)
if(grid[i][j]==1) in[j]--;
ans[cur]=lt[i];
dfs(cur+1);
for(int j=0; j<n; ++j)
if(grid[i][j]==1) in[j]++;
use[i]=false;
}
}
}
int main()
{
char c;
int kase=0;
while(scanf("%c",&c)!=EOF)
{
memset(in,0,sizeof(in));
memset(grid,0,sizeof(grid));
memset(lt,0,sizeof(lt));
memset(use,0,sizeof(use));
memset(ans,0,sizeof(ans));
mp.clear();
n=0;
lt[n++]=c;
while(scanf("%c",&c)&&c!='\n')
if(isalpha(c)) lt[n++]=c;
sort(lt,lt+n);
for(int i=0; i<n; ++i)
mp[lt[i]]=i;
char a,b;
while(scanf("%c%c%c%c",&a,&c,&b,&c))
{
int x=mp[a],y=mp[b];
grid[x][y]=1;
in[y]++;
if(c=='\n') break;
}
if(kase) printf("\n");
dfs(0);
kase++;
}
return 0;
}