您的位置:首页 > 其它

[bzoj1059] [ZJOI2007]矩阵游戏

2017-02-25 21:04 387 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1059

我好菜啊,想了好久不知道怎么做。。

然后去黄学长博客看了一眼: "不管怎么交换,同行的还是同行,同列的还是同列,所以求的是n个不同行列的点"

瞬间就会做了......

二分图匹配,每一行和每一列看作一个点,某行某列如果是1那么它们之间连边。

想着这下不会wa了吧 结果flag秒收,发现边表忘了开两倍....

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define S 0
#define T 401
#define INF 200000000
#define ms(x) memset(x,0,sizeof(x))
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}

struct edge{
int to,next,w;
}e[90005];
int head[T+5];
int n,cnt,ans;
int q[T+5];
queue<int> qu;

inline void INS(int f,int t,int w)
{e[++cnt]=(edge){t,head[f],w};head[f]=cnt;}
inline void ins(int f,int t,int w){INS(f,t,w);INS(t,f,0);}

int dfs(int x,int f)
{
if(x==T) return f;
int used=0;
for(int i=head[x];i;i=e[i].next)
if(e[i].w&&q[e[i].to]==q[x]+1)
{
int w=dfs(e[i].to,min(f-used,e[i].w));
used+=w;
e[i].w-=w;
e[i^1].w+=w;
if(used==f) return used;
}
if(!used) q[x]=-1;
return used;
}

bool bfs()
{
for(int i=1;i<=T;i++) q[i]=-1;q[S]=0;
qu.push(S);
while(!qu.empty())
{
int u=qu.front();qu.pop();
for(int i=head[u];i;i=e[i].next)
if(e[i].w&&q[e[i].to]==-1)
q[e[i].to]=q[u]+1,qu.push(e[i].to);
}
return q[T]!=-1;
}

int main()
{
int qq=read();
while(qq--)
{
cnt=1;ans=0;ms(head);
n=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if((read())==1)
ins(i,j+n,1);
for(int i=1;i<=n;i++) ins(S,i,1),ins(i+n,T,1);
while(bfs()) ans+=dfs(S,INF);
if(ans==n) puts("Yes");
else puts("No");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: