当前位置: 代码迷 >> 综合 >> POJ1270 Following Orders——拓扑排序(DFS回溯+按字典序输出所有情况)
  详细解决方案

POJ1270 Following Orders——拓扑排序(DFS回溯+按字典序输出所有情况)

热度:32   发布时间:2024-02-13 12:36:23.0

点这里


题意: 多组输入,每组输入的第一行列出受约束的字符。第二行每对字符a、b表示a必须排在b的前面。要求输出所有可行的情况,按字典序排序。结尾用空行分开。
题解: 不同以往的数字,这次受约束的是小写字母,可以在排序之后将字母转换成数字,也可以利用map来解决。因为要输出所有可行的情况,所以需要用DFS,并且还得回溯。


过程中犯的错:

  • 字典序。 又是偷懒读题,因为题面是英文的,缺乏耐心,以为自己读懂题就不继续往下读了,然后就漏了这么一个大条件。
  • 第二行约束条件的获取。 读完题目自然知道清楚每两个字符构成一对。然后每个字母之间都用空格隔开,那么自然就能推到出每个字母的下标,所以我写出了下面这个程序。应该说有点想当然了,后来这里改了就能通过。
for(int i = 2; line[i]; i += 4){char a = line[i - 2], b = line[i];v[a - 'a'].push_back(b);deg[b]++;
}

直接处理字符,DFS中传字符串

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
using namespace std;
const int N = 1000;char line[N], s[N];
string str;
vector<char> v[N];
map<char, int> deg;
void DFS(string ans){if(ans.length() == str.length()){cout << ans << endl;	return;}	for(int i = 0; str[i]; i++){string tem = ans;if(deg[str[i]] == 0){deg[str[i]]--;for(int j = 0; j < v[str[i] - 'a'].size(); j++)	deg[v[str[i] - 'a'][j]]--;tem += str[i]; DFS(tem);deg[str[i]]++;for(int j = 0; j < v[str[i] - 'a'].size(); j++)	deg[v[str[i] - 'a'][j]]++;}}
}
int main(){while(gets(line) != NULL){int cnt = 0; deg.clear();	str = "";for(int i = 0; i < 30; i++)	 v[i].clear();for(int i = 0; line[i]; i++)if(line[i] >= 'a' && line[i] <= 'z')	str += line[i];sort(str.begin(), str.end());gets(line);int flag = 1;char u, t;for(int i = 0; line[i]; i++){if(line[i] >= 'a' && line[i] <= 'z'){if(flag)	u = line[i], flag = 0;else{t = line[i], flag = 1;v[u - 'a'].push_back(t);deg[t]++;}}}string ans = "";DFS(ans); puts("");}return 0;
}

字符转成数字,DFS中传字符长度

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<map>
using namespace std;
const int N = 1e3 + 10;int G[N][N], deg[N], cnt;
char line[N], str[N], ans[N];
map<char, int> mp;
void DFS(int len){if(len == cnt){	printf("%s\n", ans); return ;}for(int i = 0; i < cnt; i++){if(deg[i] == 0){deg[i]--;ans[len] = str[i];for(int j = 0; j < cnt; j++)	if(G[i][j])	deg[j]--;DFS(len + 1);deg[i]++;for(int j = 0; j < cnt; j++)	if(G[i][j])	deg[j]++;}}
}
void init(){cnt = 0;memset(G, 0, sizeof G);memset(ans, 0, sizeof ans);memset(deg, 0, sizeof deg);mp.clear();
}
int main(){while(gets(line) != NULL){init();for(int i = 0; line[i]; i++) if(line[i] >= 'a' && line[i] <= 'z') str[cnt++] = line[i];sort(str, str + cnt);for(int i = 0; i < cnt; i++)	mp[str[i]] = i;gets(line);int flag = 1, tem1, tem2;for(int i = 0; line[i]; i++)if(line[i] >= 'a' && line[i] <= 'z')if(flag)	tem1 = mp[line[i]], flag = 0;else{tem2 = mp[line[i]], flag = 1;deg[tem2]++;G[tem1][tem2] = 1;}DFS(0); puts("");}return 0;
}