×

第九篇:P1129

题解补完计划:第九篇

怎么都第九篇了?

原题题面

显然,在最终状态,是 \((1,1), (2,2) ..., (n,n)\) 我们看成对于行和列连边,那么对于每个都有连边。我们看交换操作,其本质就是将两行或两列的连接状态交换,意思是只要有两个点的连边,那么它就可以交换,所以我们只需要知道初始状态有没有 \(n\) 的匹配就可以了,这个最大流解决就可以了,只需要判断最大流是不是 \(n\) 就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define N 100005
#define intl long long
#define inf (0x7fffffff)
#define For(i,a,b) for(intl i=a;i<=b;i++)
#define deo(i,a,b) for(intl i=a;i>=b;i--)
intl read() {
	intl x=0,k=1;char ch=getchar();
	while(!isdigit(ch)) {if(ch == '-') k=-1;ch=getchar();}
	while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*k;
}
struct edge {
	intl to, nxt, data;
}e[N<<1];
intl dep[N], h[N], cnt = 1, s, t;
void add(intl from,intl to,intl data) {
	e[++cnt]={to,h[from],data};h[from] = cnt;
}
bool bfs() {
	For(i,0,t) dep[i] = 0;
	dep[s] = 1;
	queue<intl> q;q.push(s);
	while(q.size()) {
		intl u = q.front();q.pop();
		for(intl i=h[u];i;i=e[i].nxt) {
			intl v = e[i].to;
			if(!dep[v] && e[i].data > 0) dep[v] = dep[u] + 1, q.push(v);
		}
	}
	return dep[t];
}
intl dfs(intl u,intl mx) {
	if(u == t || !mx) return mx;
	intl res = 0;
	for(intl i = h[u];i;i=e[i].nxt) {
		intl v = e[i].to;
		if(dep[v] == dep[u] + 1 && e[i].data > 0) {
			intl del = dfs(v, min(mx, e[i].data));
			if(!del) dep[v] = 0;
			res += del, mx -= del, e[i].data -= del, e[i^1].data += del;
			if(!mx) return res;
		}
	}
	return res;
}
intl dinic() {
	intl res = 0, x;
	while(bfs()) while(x = dfs(s,inf)) res += x;
	return res;
}
intl n;
int main() {
	intl T = read();
	while(T --) {
		n = read();
		For(i,1,n) For(j,1,n) {
			intl x = read();
			if(x) add(i,j+n,1), add(j+n,i,0);
		}
		s = 0, t = n+n+1;
		For(i,1,n) add(s,i,1), add(i,s,0), add(i+n,t,1),add(t,i+n,0);
		intl ans = dinic();
		if(ans == n) puts("Yes");else puts("No");
		For(i,0,t) h[i] = 0;cnt = 1;
		
	}
	return 0;
}


posted @ 2026-10-05 17:27  shiori123  阅读(5)  评论(0)    收藏  举报