网络流求调
查看原帖
网络流求调
999274
CNS_5t0_0r2楼主2024/12/19 13:51
#include<bits/stdc++.h>
using namespace std;
const int N = 1009,B = 29,M = N * B;
int nl,nr;
int s,t;
int rnk[N][B];
int cap[B];
int l = 1,r = 1,ans;
bool check(int i,int j){
    if(i > j)
        swap(i,j);
    j -= nl;
    return rnk[i][j] >= l && rnk[i][j] <= r;
}
struct Graph{
	struct edge{
		int to,cap,nex;
		int typ;
	} e[M << 1];
	int head[N + B],ecnt = 1;
	int head2[N + B];//分层图的表头 
	void addedge(int u,int v,int c,int typ){
		ecnt++;
		e[ecnt] = (edge){v,c,head[u],typ};
		head[u] = ecnt;
	}
} G,tmp;
queue<int> q;
int dep[N << 1];//层次 
bool bfs(){//构造分层图 
	memset(dep,0,sizeof dep);
	q.push(s);
	dep[s] = 1;
	G.head2[s] = G.head[s];
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i = G.head[u];i;i = G.e[i].nex){
			int v = G.e[i].to,c = G.e[i].cap;
			if(G.e[i].typ == 1 && !check(u,v))
				continue;
			if(dep[v] || !c)
				continue;
			G.head2[v] = G.head[v];
			dep[v] = dep[u] + 1;
			q.push(v);
		}
	}
	return dep[t];
}
int dfs(int u,int flow){//在分层图上增广 
	if(u == t)
		return flow;
	int rest = flow,tmp;
	for(int i = G.head2[u];i && rest;i = G.e[i].nex){
		G.head2[u] = i;
		int v = G.e[i].to,c = G.e[i].cap;
		if(dep[v] != dep[u] + 1 || !c)
			continue;
		if(G.e[i].typ == 1 && !check(u,v))
			continue;
		tmp = dfs(v,min(rest,c));
		if(!tmp)
			dep[v] = 0;//当无法从v增广时,将v从分层图中删除
		G.e[i].cap -= tmp;
		G.e[i ^ 1].cap += tmp;
		rest -= tmp;
	}
	return flow - rest;//流到u的流量减去流出u后剩余的流量就是流到汇点的流量
}
int dinic(){
	G = tmp;
	int flow = 0,ret = 0;
	while(bfs())
		while(flow = dfs(s,nl + 1))
			ret += flow;
	return ret;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin >> nl >> nr;
	for(int i = 1;i <= nl;i++){
		for(int j = 1;j <= nr;j++){
			int tmp;
			cin >> tmp;
			rnk[i][tmp] = j;
		}
	}
	for(int i = 1;i <= nr;i++)
		cin >> cap[i];
	s = 0;t = nl + nr + 1;
	for(int i = 1;i <= nl;i++){
		for(int j = 1;j <= nr;j++){
			G.addedge(i,j + nl,1,1);
			G.addedge(j + nl,i,0,1);
		}
	}
	for(int i = 1;i <= nl;i++){
		G.addedge(s,i,1,2);
		G.addedge(i,s,0,2);
	}
	for(int i = nl + 1;i <= nl + nr;i++){
		G.addedge(i,t,cap[i - nl],2);
		G.addedge(t,i,0,2);
	}
	tmp = G;
	ans = nr;
	while(l <= nr){
		while(r <= nr && dinic() < nl)
			r++;
		ans = min(ans,r - l + 1);
		l++;
	}
	cout << ans;
	return 0;
}
2024/12/19 13:51
加载中...