qoj10536 Card Flipping

题意

给出 \(n\) 组二元组 \((a_i,b_i)\),从每组二元组中选出一个元素,使得不同元素数量最多。

\(n\le 2\times 10^5,a_i,b_i\le 10^6\)

思路

网络流秒了。

多开 \(n\) 个点存每组二元组,源点连这 \(n\) 个点,每个点连 \(a_i,b_i\),每个元素连到汇点,流量均为 \(1\)

可以发现这是一个二分图,时间复杂度 \(O(n\sqrt{n})\),可以通过。

代码

#include <bits/stdc++.h>
using namespace std;
#define ll long long
namespace mf{
	const int N=1200005,INF=0x3f3f3f3f;
	struct node{
		int x,w,rev;
	};
	vector<node> t[N];
	int dep[N],gap[N],maxflow;
	int n,S,T;
	void init(int nn){
		for(int i=1;i<=nn+2;i++)
			t[i].clear();
		n=nn+2,S=nn+1,T=nn+2;
	}
	void add(int x,int y,int w){
		t[x].push_back({y,w,t[y].size()});
		t[y].push_back({x,0,t[x].size()-1});
	}
	void bfs(){
		memset(gap,0,sizeof(gap));
		memset(dep,-1,sizeof(dep));
		queue<int> q;
		q.push(T),dep[T]=0,gap[dep[T]]++;
		while(!q.empty()){
			int u=q.front();q.pop();
			for(node v:t[u])
				if(!~dep[v.x])
					dep[v.x]=dep[u]+1,gap[dep[v.x]]++,q.push(v.x);
		}
	}
	int dfs(int x,int flow){
		if(x==T) return maxflow+=flow,flow;
		int used=0;
		for(auto&[v,w,rev]:t[x]){
			if(w&&dep[v]+1==dep[x]){
				int mn=dfs(v,min(w,flow-used));
				if(mn) w-=mn,t[v][rev].w+=mn,used+=mn;
				if(flow==used) return used;
			}
		}
		gap[dep[x]]--;
		if(!gap[dep[x]]) dep[S]=n+1;
		dep[x]++,gap[dep[x]]++;
		return used;
	}
	int isap(){
		maxflow=0;
		bfs();
		if(dep[S]==-1) return 0;
		while(dep[S]<n) dfs(S,INF);
		return maxflow;
	}
}
int n,a[200005],b[200005];
signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr),cout.tie(nullptr);
	cin>>n;
	mf::init(1e6+1+n);
	for(int i=1;i<=n;i++) cin>>a[i],a[i]++;
	for(int i=1;i<=n;i++) cin>>b[i],b[i]++;
	for(int i=1;i<=n;i++)
		mf::add(mf::S,1000001+i,1),mf::add(1000001+i,a[i],1),mf::add(1000001+i,b[i],1);
	for(int i=1;i<=1000001;i++)
		mf::add(i,mf::T,1);
	cout<<mf::isap();
	return 0; 
}
posted @ 2025-09-02 20:42  WuMin4  阅读(22)  评论(0)    收藏  举报