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