/*
DFS拓扑排序,要注意局部状态的记录
建图的方法:如果矩形a是紧邻b上方的矩形,则graph[a][b] = true
DFS时,每次记录上一次用到的刷子的颜色,然后从当前记忆保存的graph中
寻找入度为0的矩形,如果其颜色不等于上一次用到的刷子的颜色,则总数+1,
然后从新的矩形中清除掉以这个矩形为端点的变,继续下一次DFS
*/
#include <iostream>
#define MAX_N 15
using namespace std;
bool graph[MAX_N + 1][MAX_N + 1];
int n, minNum;
struct rec
{
int x1, y1, x2, y2;
int color;
}recs[MAX_N + 1];
bool onup(const rec &c1, const rec &c2)
{
bool check1 = c1.y2 == c2.y1;
bool check2 = (c2.x1 >= c1.x1 && c2.x1 < c1.x2) || (c2.x2 <= c1.x2 && c2.x2 > c1.x1);
return check1 && check2;
}
//graph[i][i]有特殊用途,记忆矩形i是否被刷过,如果graph[i][i] = true则没有被刷过
void topnology(int curNum, int lastColor, bool graph[][MAX_N + 1])
{
if(curNum > minNum) return;
int i, j, k;
bool goon = false;
for(i = 1; i <= n; i++)
{
if(!graph[i][i]) continue;
bool can = true;
for(j = 1; j <= n && can; j++)
if(i != j && graph[j][i]) can = false;
if(can)
{
goon = true;
bool tempG[MAX_N + 1][MAX_N + 1];
for(j = 1; j <= n; j++)
{
for(k = 1; k <= n; k++)
{
if(j == i || k == i) tempG[j][k] = false;
else tempG[j][k] = graph[j][k];
}
}
tempG[i][i] = false;
int newNum = (lastColor == recs[i].color) ? curNum : curNum + 1;
topnology(newNum, recs[i].color, tempG);
}
}
if(!goon)
{
if(curNum < minNum)
minNum = curNum;
}
}
int main()
{
int caseNum, i, j;
scanf("%d", &caseNum);
while(caseNum--)
{
scanf("%d", &n);
memset(graph, 0, sizeof(graph));
for(i = 1; i <= n; i++)
{
graph[i][i] = true;
scanf("%d%d%d%d%d", &recs[i].y1, &recs[i].x1, &recs[i].y2, &recs[i].x2, &recs[i].color);
for(j = 1; j < i; j++)
{
if(onup(recs[i], recs[j])) graph[i][j] = true;
if(onup(recs[j], recs[i])) graph[j][i] = true;
}
}
minNum = INT_MAX;
topnology(0, -1, graph);
printf("%d/n", minNum);
}
return 0;
}
POJ 1691 Painting A Board
最新推荐文章于 2020-07-17 16:00:17 发布