首页 > 代码库 > poj 1691 Painting A Board(dfs,拓扑排序)
poj 1691 Painting A Board(dfs,拓扑排序)
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-8 using 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; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。