poj 1691 Painting A Board (拓扑排序+dfs)

来源:互联网 发布:2017淘宝主图尺寸大小 编辑:程序博客网 时间:2024/06/05 19:06

题目链接: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();//dfsmmax = 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,看来自己......

原创粉丝点击