poj 1691 Painting A Board

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

拓扑排序+DFS

把矩形的先后顺序 用拓扑排序构造

再进行深搜+剪枝就可以啦

代码:

#include<iostream>

#include<cstdio>

#include<cstring>

#include<string>

#include<cmath>

#include<queue>

#include<algorithm>

#include<set>



using namespace std;



const int N=21;

struct node

{

    int x1,y1,x2,y2,c;

}mem[N];

int pn[N][N];

int num[N];

bool had[N];

int ans,n;

void Dfs(int sum,int prec,int m)

{

    if(m==n)

    {

        ans=min(ans,sum);

        return;

    }

    for(int i=0;i<n;++i)

    {

        if(!had[i]&&num[i]==0)

        {

            int s=sum;

            if(mem[i].c!=prec)

            ++s;

            if(s<ans)

            {

                for(int j=0;j<n;++j)

                {

                    if(pn[i][j]==2)

                    {--pn[i][j];--num[j];}

                }

                had[i]=true;

                Dfs(s,mem[i].c,m+1);

                had[i]=false;

                for(int j=0;j<n;++j)

                {

                    if(pn[i][j]==1)

                    {++pn[i][j];++num[j];}

                }

            }



        }

    }

}

int main()

{

   int M;

   scanf("%d",&M);

   while(M--)

   {

       scanf("%d",&n);

       for(int i=0;i<n;++i)

       {

           scanf("%d %d %d %d %d",&mem[i].y1,

                 &mem[i].x1,&mem[i].y2,&mem[i].x2,&mem[i].c);

       }

       memset(num,0,sizeof(num));

       memset(pn,0,sizeof(pn));

       for(int i=0;i<n;++i)

       {

           for(int j=0;j<n;++j)

           {

               if(i!=j)

               {

                   if(mem[j].y2==mem[i].y1&&

                      !(mem[i].x2<=mem[j].x1||mem[i].x1>=mem[j].x2))

                  {

                     pn[j][i]=2;

                     ++num[i];

                  }

               }

           }

       }

       ans=n;

       memset(had,false,sizeof(had));

       Dfs(0,0,0);

       printf("%d\n",ans);

   }

   return 0;

}

  

你可能感兴趣的:(paint)