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

来源:互联网 发布:xp 保存网络用户密码 编辑:程序博客网 时间:2024/05/18 02:52

http://poj.org/problem?id=1691


大致题意:给出n个矩形,其参数有左上角顶点坐标,右下角顶点坐标以及该矩形所涂颜色。规定是涂当前矩形当且仅当它上面的矩形都已经被涂了色。若当前涂的颜色和上一个所涂的不同,就要换一种颜色的刷子。问应该按怎样的顺序给这n个矩形涂色使换的刷子总数最少。


思路:显然涂色是有先后顺序的,就很容易想到拓扑排序。那么首先根据矩形相交建立一个矩形之间的有向图,然后求出所有的拓扑排序,同时比较出所换刷子最少的即可。


#include <stdio.h>#include <iostream>#include <algorithm>#include <set>#include <map>#include <vector>#include <math.h>#include <string.h>#include <queue>#include <string>#include <stdlib.h>#define LL long long#define _LL __int64#define eps 1e-8using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 10;struct node{int x1,y1,x2,y2;int col;}rec[20];int n;int Map[20][20];int in[20],vis[20];int ans;//求出所有的拓扑排序,每次找一个未访问的入度为0的点进行拓扑,最后要更改回来状态void dfs(int num, int pre_col, int col){if(col > ans)return;if(num == n){if(col < ans)ans = col;return;}for(int i = 1; i <= n; i++){if(!vis[i] && in[i] == 0){vis[i] = 1;for(int j = 1; j <= n; j++)if(Map[i][j] == 1)in[j]--;if(rec[i].col == pre_col)dfs(num+1,pre_col,col);else dfs(num+1,rec[i].col,col+1);vis[i] = 0;for(int j = 1; j <= n; j++)if(Map[i][j] == 1)in[j]++;}}}int main(){int test;scanf("%d",&test);while(test--){scanf("%d",&n);for(int i = 1; i <= n; i++){scanf("%d %d %d %d %d",&rec[i].x1,&rec[i].y1,&rec[i].x2,&rec[i].y2,&rec[i].col);}memset(Map,0,sizeof(Map));memset(in,0,sizeof(in));memset(vis,0,sizeof(vis));ans = INF;for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){if(i == j) continue;//注意判断矩形相交,没考虑周全,1WA。if(rec[j].x2 == rec[i].x1 && ( (rec[j].y2 > rec[i].y1 && rec[j].y2  <= rec[i].y2) || (rec[j].y1 < rec[i].y2 && rec[j].y1 >= rec[i].y1))){Map[j][i] = 1;in[i] += 1;}}}dfs(0,-1,0);printf("%d\n",ans);}return 0;}


0 0
原创粉丝点击