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

  

posted @ 2012-03-07 00:11  快乐.  阅读(217)  评论(0编辑  收藏  举报