码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2007]矩阵游戏

时间:2018-12-05 10:23:47      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:add   最大   n+1   二分图最大匹配   void   else   read   printf   type   

很容易想到去吧棋盘模型转为二分图。
发现是一个类似行列匹配的问题。
进一步,如果每一个行都可以找到一个列与之配对的话,一定可以通过交换满足要求。
直接dinic求二分图最大匹配即可。

#include<iostream>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<cstdlib>
#include<algorithm>
#define N 110000
#define eps 1e-7
#define inf 1e9+7
#define ll long long
using namespace std;
inline int read()
{
    char ch=0;
    int x=0,flag=1;
    while(!isdigit(ch)){ch=getchar();if(ch==‘-‘)flag=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
    return x*flag;
}
struct edge
{
    int to,nxt,w;
}e[N*2];
int num,head[N];
inline void add(int x,int y,int z)
{
    e[++num]=(edge){y,head[x],z};head[x]=num;
    e[++num]=(edge){x,head[y],0};head[y]=num;
}
queue<int>q;
int n,m,s,t,dep[N];
bool bfs()
{
    for(int i=0;i<=t;i++)dep[i]=0;
    dep[s]=1;q.push(s);
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        for(int i=head[x];i!=-1;i=e[i].nxt)
        {
            int to=e[i].to;
            if(!dep[to]&&e[i].w)
            {
                dep[to]=dep[x]+1;
                q.push(to);
            }
        }
    }
    return dep[t];
}
int dfs(int x,int flow)
{
    if(x==t)return flow;
    for(int i=head[x];i!=-1;i=e[i].nxt)
    {
        int to=e[i].to;
        if(dep[to]==dep[x]+1&&e[i].w)
        {
            int w=dfs(to,min(flow,e[i].w));
            if(w)
            {
                e[i].w-=w;
                e[i^1].w+=w;
                return w;
            }
        }
    }
    return 0;
}
void work()
{
    int n=read(),i,j,w,maxflow=0;
    num=-1;memset(head,-1,sizeof(head));
    for(i=1;i<=n;i++)
      for(j=1;j<=n;j++)
      if(read())add(i,j+n,1);
    s=2*n+1;t=2*n+2;
    for(i=1;i<=n;i++)
    {
        add(s,i,1);
        add(i+n,t,1);
    }
    while(bfs())
    {
        do
        {
            w=dfs(s,inf);
            maxflow+=w;
        }while(w);
    }
    if(maxflow==n)printf("Yes\n");
    else printf("No\n");
    return;
}
int main()
{
    int t=read();
    for(int i=1;i<=t;i++)work();
    return 0;
}

[ZJOI2007]矩阵游戏

标签:add   最大   n+1   二分图最大匹配   void   else   read   printf   type   

原文地址:https://www.cnblogs.com/Creed-qwq/p/10068810.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!