POJ 1691

其实这道题一开始没有什么思路,是别人带了节奏之后我一问是DFS加拓扑,上下相邻的连一条边(由上指向下)瞬间就明白了:

代码也很简单,我这么粗心的家伙都1A,就不多解释了,直接上代码:

/*Problem: 1691		User: Burglar
Memory: 656K		Time: 32MS
Language: G++		Result: Accepted
*/
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#define MAXN 20
#define INF 10000000
using namespace std;
struct Matrix
{
    int lx,ly;//左上角的左边
    int rx,ry;//右上角的坐标
    int color;//矩阵颜色
}matrix[MAXN];
int n,degree[MAXN],path[MAXN][MAXN];//TOP数组
int judge[MAXN];//在DFS是标记是否已经涂过颜色
int min_ans;//答案
bool have_path(Matrix a,Matrix b)//用于在TOP构图时判断矩阵a是否在矩阵b下方并且相邻
{
    if(a.ly==0) return false;
    else if(a.ly==b.ry)
    {
        if(a.lx>=b.rx||a.rx<=b.lx) return false;
        else
            return true;
    }
    else
        return false;
}
int Min(int a,int b)
{
    if(a<b) return a;
    else
        return b;
}
void dfs(int now_color,int time,int done)//DFS枚举答案,没什么需要多说的;三个参数从左至右的意义依次是:现在机器人手中的刷子颜色;换刷子的次数;已经涂完的矩阵数;
{
    if(time>min_ans) return;
    if(done==n)
    {
        min_ans=Min(min_ans,time);
        return;
    }
    else
    {
        for(int i=0;i<n;i++)
        {
            if(degree[i]==0&&judge[i]==0)
            {
                judge[i]=1;
                for(int j=0;j<n;j++)
                {
                    if(j==i) continue;
                    else
                    {
                        if(path[i][j])
                        {
                            degree[j]--;
                        }
                    }
                }
                if(now_color==matrix[i].color) dfs(now_color,time,done+1);
                else
                    dfs(matrix[i].color,time+1,done+1);
                for(int j=0;j<n;j++)
                {
                    if(j==i) continue;
                    else
                    {
                        if(path[i][j])
                        {
                            degree[j]++;
                        }
                    }
                }
                judge[i]=0;
            }
        }
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        //注意初始化
        memset(matrix,0,sizeof(matrix));
        memset(degree,0,sizeof(degree));
        memset(judge,0,sizeof(judge));
        memset(path,0,sizeof(path));
        min_ans=INF;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d%d%d",&matrix[i].ly,&matrix[i].lx,&matrix[i].ry,&matrix[i].rx,&matrix[i].color);
        }
        for(int i=0;i<n;i++)//TOP构图
        {
            for(int j=0;j<n;j++)
            {
                if(i==j) continue;
                else
                {
                    if(have_path(matrix[i],matrix[j]))
                    {
                        path[j][i]=1;
                        degree[i]++;
                    }
                }
            }
        }
        dfs(0,0,0);
        printf("%d\n",min_ans);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值