链接:http://poj.org/problem?id=1128
题意:有几张图片,给你叠加到一起之后的图,问叠加的可能性,如有多种可能则按字典序由小到大输出。
思路:根据给出的图形建一个图,被覆盖的图片向覆盖它的图片建边,然后拓扑排序。
拓扑排序按照字母顺序从小到大找入度为0的点,用dfs形式的拓扑排序,就按照字典序输出了。
POJ1270的做法也类似: 代码
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<deque>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 35
#define eps 1e-7
#define INF 0x3F3F3F3F //0x7FFFFFFF
#define LLINF 0x7FFFFFFFFFFFFFFF
#define seed 1313131
#define MOD 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct node{
int x, y;
}left_top[MAXN], right_bottom[MAXN];
int n, m, tot;
int edge[MAXN][MAXN], in[MAXN];
char mapp[MAXN][MAXN];
char str[MAXN];
int vis[MAXN];
void dfs(int len){
int i, j;
if(len == tot){
puts(str);
return ;
}
for(i = 0; i < 26; i++){
if(!vis[i]) continue;
if(in[i] == 0){
in[i] = -1;
str[len] = i + 'A';
for(j = 0; j < 26; j++){
if(edge[i][j]) in[j]--;
}
dfs(len + 1);
for(j = 0; j < 26; j++){
if(edge[i][j]) in[j]++;
}
in[i] = 0;
}
}
}
int main(){
int i, j, k;
while(scanf("%d%d", &n, &m) != EOF){
memset(edge, 0, sizeof(edge));
memset(in, 0, sizeof(in));
memset(vis, 0, sizeof(vis));
memset(str, 0, sizeof(str));
for(i = 0; i < MAXN; i++){
left_top[i].x = left_top[i].y = INF;
right_bottom[i].x = right_bottom[i].y = 0;
}
for(i = 0; i < n; i++) scanf("%s", mapp[i]);
for(i = 0; i < n; i++){
for(j = 0; j < m; j++){
if(mapp[i][j] == '.') continue;
int temp = mapp[i][j] - 'A';
if(left_top[temp].x > i) left_top[temp].x = i;
if(left_top[temp].y > j) left_top[temp].y = j;
if(right_bottom[temp].x < i) right_bottom[temp].x = i;
if(right_bottom[temp].y < j) right_bottom[temp].y = j;
}
}
tot = 0;
for(i = 0; i < 26; i++){
if(left_top[i].x == INF) continue;
tot++;
vis[i] = 1;
for(j = left_top[i].x; j <= right_bottom[i].x; j++){
if(mapp[j][left_top[i].y] != i + 'A') edge[i][mapp[j][left_top[i].y] - 'A'] = 1;
if(mapp[j][right_bottom[i].y] != i + 'A') edge[i][mapp[j][right_bottom[i].y] - 'A'] = 1;
}
for(j = left_top[i].y + 1; j <= right_bottom[i].y - 1; j++){
if(mapp[left_top[i].x][j] != i + 'A') edge[i][mapp[left_top[i].x][j] - 'A'] = 1;
if(mapp[right_bottom[i].x][j] != i + 'A') edge[i][mapp[right_bottom[i].x][j] - 'A'] = 1;
}
}
for(i = 0; i < MAXN; i++){
for(j = 0; j < MAXN; j++){
if(edge[i][j]) in[j]++;
}
}
dfs(0);
}
return 0;
}