首页 > 代码库 > POJ 1691 Painting A Board

POJ 1691 Painting A Board

题目大意:

墙上有一块区域被分成了n个矩形,每个矩形要涂上各自的颜色。为了保证完美要求这一块区域可以进行涂色的条件是它上方的所有区域都已经涂好颜色,这样就不会有后续的操作影响这块区域的颜色。但是如果两块区域颜色不同就要换涂颜色用的刷子。问最少需要换几次。


解题思路:

区域涂色的大体次序是由拓扑排序决定的,当有多个区域在同一层次时需要枚举这些区域来保证换刷子的次数最小。



下面是代码:

#include <stdio.h>
#include <stdlib.h>

struct node1
{
    int x1,y1,x2,y2,c,status;
} node[100];
int cnt,min1,n,edgecnt;
struct edge1
{
    int u,v,next;
} edge[100];
int head[20];
void addedge(int u,int v)
{
    edge[edgecnt].v=v;
    edge[edgecnt].u=u;
    edge[edgecnt].next=head[u];
    head[u]=edgecnt++;
    node[v].status++;
}
int min(int a,int b)
{
    if(a>b)a=b;
    return a;
}
void dfs(int num,int col)
{
    //printf("%d %d %d\n",num,col,cnt);
    if(num==0)
    {
        min1=min(min1,cnt);
        return ;
    }
    for(int i=0; i<n; i++)
    {
        if(node[i].status==0)
        {
            int p=head[i];
            while(p!=-1)
            {
             node[edge[p].v].status--;
                p=edge[p].next;
            }
            if(col!=node[i].c)cnt++;
            node[i].status=-1;
            dfs(num-1,node[i].c);
            node[i].status=0;
            p=head[i];
            while(p!=-1)
            {
                node[edge[p].v].status++;
                p=edge[p].next;
            }
            if(col!=node[i].c)cnt--;
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        {
            scanf("%d%d%d%d%d",&node[i].y1,&node[i].x1,&node[i].y2,&node[i].x2,&node[i].c);
            node[i].status=0;
            head[i]=-1;
        }
        edgecnt=0;
        min1=10000000;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if(node[i].y2==node[j].y1&&!(node[j].x1>node[i].x2||node[i].x1>node[j].x2))
                {
                    addedge(i,j);
                }
            }
        }
        cnt=0;
        dfs(n,-1);
        printf("%d\n",min1);
    }
    return 0;
}