POJ 1691 Painting A Board
把每个方形看成一个点,如果先染a,再染b,a->b有向线,如果入度为0就可以染了。构图跟拓扑排序似的,
然后搜索回溯方法跟zoj1004差不多
代码:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #define Min(a,b)a<b?a:b using namespace std; int map[20][20],vs[20],deg[20]; int n,ans; struct Node { int x1,y1,x2,y2,c; }node[20]; void buildGra() { int i,j; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(node[i].y2==node[j].y1&& !(node[i].x1>node[j].x2||node[i].x2<node[j].x1)) { deg[j]++; map[i][j]=1; } } return ; } void dfs(int dep,int cnt,int color) { if(cnt>=ans)return ; if(dep==n) { ans=Min(ans,cnt); return ; } int i,j; for(i=1;i<=n;i++) { if(deg[i]==0&&!vs[i]) { vs[i]=1; for(j=1;j<=n;j++) { if(map[i][j])deg[j]--; } if(node[i].c==color)dfs(dep+1,cnt,color); else dfs(dep+1,cnt+1,node[i].c); for(j=1;j<=n;j++) if(map[i][j])deg[j]++; vs[i]=0; } } } int main() { int CASE,i; scanf("%d",&CASE); while(CASE--) { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d%d%d%d%d",&node[i].y1,&node[i].x1, &node[i].y2,&node[i].x2,&node[i].c); } memset(map,0,sizeof(map)); memset(deg,0,sizeof(deg)); buildGra(); memset(vs,0,sizeof(vs)); ans=50; dfs(0,0,0); printf("%d\n",ans); } return 0; }