[省选前题目整理][BZOJ 1059][ZJOI 2007]矩阵游戏(二分图最大匹配)

142 篇文章 0 订阅
98 篇文章 0 订阅

题目链接

http://www.lydsy.com/JudgeOnline/problem.php?id=1059

思路

实际上在这个游戏中,我们可以随心所欲地将任意一个格子移动到指定的位置上去,进一步的研究还可以发现,每一行只能有一个格子被移动,每一列也只能有一个格子被移动。那么要想达到最终这个n*n的棋盘的对角线上都是黑格子,就需要有n个黑格子(xi,yi),而且任意的xi均不相同,任意的yi均不相同。那么我们可以想到二分图建模,将行号当成x侧的点,将列号当成y侧的点,对于任意的黑格子(xi,yi),xi向yi连一条边,对这个建好的二分图跑最大匹配,最后检查所有的x点(y点)是否都被匹配上了,若都被匹配上了,则此游戏有解,否则此游戏无解。

代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>

#define MAXE 61000
#define MAXV 1000

using namespace std;

int n;

struct edge
{
    int u,v,next;
}edges[MAXE];

int head[MAXV],nCount=0;

void AddEdge(int U,int V)
{
    edges[++nCount].u=U;
    edges[nCount].v=V;
    edges[nCount].next=head[U];
    head[U]=nCount;
}

int vis_cnt=0,pre[MAXV],vis[MAXV];

bool find(int u)
{
    for(int p=head[u];p!=-1;p=edges[p].next)
    {
        int v=edges[p].v;
        if(vis[v]==vis_cnt) continue;
        vis[v]=vis_cnt;
        if(pre[v]==-1||find(pre[v]))
        {
            pre[v]=u;
            return true;
        }
    }
    return false;
}

void work()
{
    memset(pre,-1,sizeof(pre));
    for(int i=1;i<=n;i++)
    {
        vis_cnt++;
        find(i);
    }
    for(int i=1;i<=n;i++)
        if(pre[i]==-1)
        {
            puts("No");
            return;
        }
    puts("Yes");
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        nCount=0;
        memset(head,-1,sizeof(head));
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                int x;
                scanf("%d",&x);
                if(x) AddEdge(i,j);
            }
        work();
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值