Bzoj 2743
Bzoj 2434

Bzoj 1059

coc youyl posted @ 2015年6月16日 23:00 in bzoj , 595 阅读

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1059

题目分类:二分图匹配,网络流

题意:

给出一个01矩阵,每次允许交换任意两行或任意两列,问能否使得结果的矩阵中一条对角线全部为1。【对别的位置没有要求】

题解:

可以发现无论如何操作,原来在同一行的还在同一行,原来在同一列的还在同一列,所以把问题转化为问矩阵中能否找到n个点使得这n个点的横坐标为1~n,纵坐标也是1~n。

然后就是二分图匹配。

程序:

#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxl=20000;
int st[maxl],ed;
struct node
{
    int next,to,fl,opt;
}g[10*maxl];
inline void add(int x,int y,int z)
{
//	printf("%d %d %d\n",x,y,z);
    ed++;
    g[ed].to=y;
    g[ed].next=st[x];
    g[ed].fl=z;
    g[ed].opt=ed+1;
    st[x]=ed;
    ed++;
    g[ed].to=x;
    g[ed].next=st[y];
    g[ed].fl=0;
    g[ed].opt=ed-1;
    st[y]=ed;
}
int x1,x2,x3,lev[maxl],des;
inline bool makelev()
{
    queue<int>q;
    q.push(0);
    memset(lev,-1,sizeof(lev));
    lev[0]=1;
    while (!q.empty())
    {
        x1=q.front();q.pop();//printf("%d ",x1);
        for (int i=st[x1];i!=0;i=g[i].next)
        {
            if(lev[g[i].to]==-1&&g[i].fl!=0)
            {
                q.push(g[i].to);
                lev[g[i].to]=lev[x1]+1;
                if(g[i].to==des){return true;}
            }
        }
    }return false;
}
int stap,sta[maxl],spre[maxl],stae[maxl];
int maxflow;
inline void extend()
{
    int del;
    stap=1;
    sta[1]=0;
    for (int i=0;i<=des;i++)
    {
        spre[i]=st[i];//printf("%d %d\n",i,st[i]);
    }
    while (stap!=0)
    {
        x1=sta[stap];
    //  printf("%d\n",x1);
        if(x1!=des)
        {
            for (;spre[x1]!=0;spre[x1]=g[spre[x1]].next)
            {
                if(g[spre[x1]].fl!=0&&lev[x1]+1==lev[g[spre[x1]].to])
                {
                    break;
                }
            }
            if(spre[x1]!=0)
            {
                stap++;
                stae[stap]=spre[x1];
                sta[stap]=g[spre[x1]].to;
            }
            else
            {
                stap--;lev[x1]=0;
            }
        }
        else
        {
            del=1050000000;
            for (int i=stap;i>=2;i--)
            {
                del=min(del,g[stae[i]].fl);
            }//printf("%d\n",del);
            maxflow+=del;
            for (int i=stap;i>=2;i--)
            {
                g[stae[i]].fl-=del;
                g[g[stae[i]].opt].fl+=del;
                if(g[stae[i]].fl==0)stap=i-1;
            }
        }
    }
}
inline void dinic()
{
    maxflow=0;
    while (makelev())extend();
}
int n,m,ff;
int main()
{
	int T;
	scanf("%d",&T);
	while (T--)
	{
		scanf("%d",&n);
		ed=0;
		des=n+n+1;
		memset(st,0,sizeof(st));
		for (int i=1;i<=n;i++)
		{
			add(0,i,1);
			add(i+n,des,1);
			for (int j=1;j<=n;j++)
			{
				scanf("%d",&ff);
				if(ff==1)add(i,j+n,1);
			}
		}
		dinic();
		if(maxflow==n)printf("Yes\n");
		else printf("No\n");
	}
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter