[bzoj1059] [ZJOI2007]矩阵游戏
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; }
FallDream代表秋之国向您问好!
欢迎您来我的博客www.cnblogs.com/FallDream