题目链接:
http://poj.org/problem?id=1691
题意:
输入T表示T组数据:
输出n表示有n个矩形:
接下来n行,每行五个数分,y1,x1,y2,x2,c分别表示其左上角坐标和右下角坐标,坐标系按题上所给建立,c表示这个矩形期望得到的颜色。
要求给每个矩形都染上自己期望的颜色,染色规则为:能给某个矩形染色当且仅当此矩形上方的所有矩形均已染色,染色时一旦染色必须是给整块矩形染色,问最少更换几次颜色可以涂完所有的矩形。
题解:
读完题意发现,一个矩形能够控制的矩形是它正下方的紧挨着它的矩形,每次必须先涂没有被控制的矩形,似乎想到了拓扑排序,至于让换颜色的次数最小,观察数据范围n小于15,唉,不用纠结,果断暴力涂色。
代码:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<vector>
#include<string.h>
using namespace std;
struct node{
int x1,x2,y1,y2;
int id,c;
}ar[21];
vector<int>lin[21];
int ans,n,T,in[21],vis[21];
void dfs(int tot,int step,int nowc)
{
if (step>=ans) return ;
if (tot==n)
{
ans=step;
return ;
}
for (int i=1;i<=n;i++)
if (in[i]==0&&vis[i]==0)
{
for (int j=0;j<lin[i].size();j++)
in[lin[i][j]]--;
vis[i]=1;
if (nowc==ar[i].c)
dfs(tot+1,step,nowc);
else
dfs(tot+1,step+1,ar[i].c);
vis[i]=0;
for (int j=0;j<lin[i].size();j++)
in[lin[i][j]]++;
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ans=999999;
for (int i=1;i<=n;i++)
{
scanf("%d%d%d%d%d",&ar[i].y1,&ar[i].x1,&ar[i].y2,&ar[i].x2,&ar[i].c);
ar[i].id=i;
lin[i].clear();
in[i]=0;vis[i]=0;
}
//建图,即建立控制关系
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (ar[j].x1<ar[i].x2&&ar[j].x2>ar[i].x1&&ar[j].y1==ar[i].y2)
{
lin[i].push_back(j);
in[j]++;
}
for (int i=1;i<=n;i++)
if (in[i]==0&&vis[i]==0)
{
vis[i]=1;
for (int j=0;j<lin[i].size();j++)
in[lin[i][j]]--;
dfs(1,1,ar[i].c);
vis[i]=0;
for (int j=0;j<lin[i].size();j++)
in[lin[i][j]]++;
}
printf("%d\n",ans);
}
}