题目链接:http://poj.org/problem?id=1691
题目大意:给你n个小矩形,可以一个大矩形。给这n个小矩形涂色,涂色的要求是:只有位于它上方的并且和它邻接的小矩形涂完了色,它才能涂色。(很明显想到拓扑排序)
用刷子给n个矩形涂色,刷子一次可以给多个符合涂色要求的相同颜色的矩形涂色。当颜色不同时,需要换刷子。问最少需要换多少次刷子?
题目的输入:样例个数,每个样例的小矩形的个数,以及每个小矩形的左上角,右下角的坐标,给该矩形涂的哪种颜色。
题目的输出:需要换刷子的最少次数。
思路:先构建图。然后用深搜和拓扑排序的思想,解决问题。
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
/*
先拓扑排序,再dfs枚举
*/
struct Point {
int x, y;
};
struct Node {
Point start, end;
int kind;
};
Node node[110];
vector<int> vect[110];
int indegree[110];
int visit[110];
int mmax, n;
void Dfs(int x, int num) {
int i, t;
if(num > n) return;
for(i=0; i<n; i++)
if(visit[i] == 0) break;
if(i == n) {
//printf("num = %d\n", num);
//printf("----------------\n");
if(num < mmax) mmax = num;
return;
}
for(i=0; i<vect[x].size(); i++) {
t = vect[x][i];
indegree[t] --;
}
for(i=0; i<n; i++)
if(indegree[i] == 0 && visit[i] == 0) {
visit[i] = 1;
if(node[i].kind != node[x].kind) Dfs(i, num+1);
else Dfs(i, num);
//printf("kind1 = %d, kind2 = %d, node = %d, num = %d\n", node[x].kind, node[i].kind, i, num);
visit[i] = 0;
}
for(i=0; i<vect[x].size(); i++) {
t = vect[x][i];
indegree[t] ++;
}
}
/*void Print() {
int i;
for(i=0; i<n; i++) printf("%d\t",indegree[i]);
printf("\n");
}*/
int main() {
int t, i, j;
//freopen("in.txt", "r", stdin);
scanf("%d", &t);
while(t--) {
scanf("%d", &n);
for(i=0; i<n; i++) {
vect[i].clear();
scanf("%d%d%d%d%d", &node[i].start.y,&node[i].start.x,&node[i].end.y,&node[i].end.x,&node[i].kind);
}
//建图
for(i=0; i<n; i++) {
indegree[i] = 0;
for(j=0; j<n; j++) {
if(node[j].end.y == node[i].start.y && node[i].end.x - node[j].start.x > 0 && node[j].end.x - node[i].start.x > 0) {
vect[j].push_back(i);
indegree[i] ++;
}
}
}
//Print();
//dfs
mmax = n;
memset(visit, 0, sizeof(visit));
for(i=0; i<n; i++) {
if(indegree[i] == 0) {
visit[i] = 1;
//printf("Go:node=%d, num = 1\n", i);
Dfs(i, 1);
visit[i] = 0;
}
}
printf("%d\n", mmax);
}
return 0;
}
总结:这个题目首先没有想到拓扑排序,而且在写dfs的时候,里面的
for(i=0; i<n; i++)
if(indegree[i] == 0 && visit[i] == 0) {
visit[i] = 1;
if(node[i].kind != node[x].kind) Dfs(i, num+1);
else Dfs(i, num);
//printf("kind1 = %d, kind2 = %d, node = %d, num = %d\n", node[x].kind, node[i].kind, i, num);
visit[i] = 0;
}
这段代码,原先是这样写的:
for(i=0; i<n; i++)
if(indegree[i] == 0 && visit[i] == 0) {
if(node[i].kind != node[x].kind) num++;
visit[i] = 1;
Dfs(i, num);
//printf("kind1 = %d, kind2 = %d, node = %d, num = %d\n", node[x].kind, node[i].kind, i, num);
visit[i] = 0;
}
自己调了很久才调出来。看来对深搜还是理解的不够深。看后面的讨论这题可以用状态压缩的dp,看来自己......