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

  

原文地址:https://www.cnblogs.com/liulangye/p/2596940.html