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;
}

浙公网安备 33010602011771号