POJ 1270 Following Orders (拓扑排序,dfs枚举)

题意:每组数据给出两行,第一行给出变量,第二行给出约束关系,每个约束包含两个变量x,y,表示x<y。

     要求:当x<y时,x排在y前面。让你输出所有满足该约束的有序集。

思路:用拓扑排序,dfs枚举即可,为简便起见,这里将字符变量转化为整型值存储。

#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <algorithm> using namespace std;
int node[],num; //num为变量的个数,node存储变量对应的整型值
int edge[][]; //edge[i][j]=1表示i<j。
int into[]; //表示i的入度
//u表示此次选的是第u个变量,idx表示目前选了idx个变了,s是输出的结果字符串
void topo_dfs(int u,int idx,string s){
if(u!=-)
s+=char(node[u]+'a');
if(idx==num){
cout<<s<<endl;
return;
}
for(int i=;i<num;i++){
//选出入度为0的变量,将与它相连的点的入度-1。
if(into[node[i]]==){
into[node[i]]=-;
for(int j=;j<;j++){
if(edge[node[i]][j]){
into[j]--;
}
}
//一开始第一个参数传了node[i]。。。
topo_dfs(i,idx+,s);
//最后别忘了恢复
into[node[i]]=;
for(int j=;j<;j++){
if(edge[node[i]][j]){
into[j]++;
}
}
}
}
}
int main() {
char str1[],str2[];
int u,v,len1,len2;
while(gets(str1)){
gets(str2);
memset(edge,,sizeof(edge));
memset(into,,sizeof(into));
num=;
len1=strlen(str1);
len2=strlen(str2);
for(int i=;i<len1;i+=){
u=str1[i];
node[num++]=u-'a';
}
//这里排序,是为了之后dfs枚举的顺序按照字典顺序
sort(node,node+num); for(int i=;i<len2;i+=){
u=str2[i]-'a';
v=str2[i+]-'a';
edge[u][v]=;
into[v]++; //注意啦,这里into的下标是v,不是node数组中的索引!!!一开始dfs中into就是用的索引,导致样例一直不过。。。
}
topo_dfs(-,,"");
puts("");
}
return ;
}
上一篇:Telegram学习解析系列(一):认识一下Telegram的源码


下一篇:POJ 1270 Following Orders(拓扑排序)题解