【题解】CF387D George and Interesting Graph

1

枚举中心,然后统计中心和其他点未建边数,统计ans

对于剩余n-1个点,限制转为一进一出,即二分图

我们只需要二分图匹配统计出当前图最大可保留边数

然后推式子即可

2

#include<bits/stdc++.h>
#define Pair pair<int,int>
#define inf 1e9
using namespace std;
const int N=1010,M=1e4+10;
int h[N],to[M],ne[M],w[M],idx=1;
void add(int a,int b,int c){
	to[++idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx;
	to[++idx]=a;w[idx]=0;ne[idx]=h[b];h[b]=idx;
}
int mp[N/2][N/2];
int n,m;
int S=0,T;

int dep[N];
int cur[N];
bool bfs(){
	for(int i=S;i<=T;i++){
		dep[i]=-1;
		cur[i]=h[i];
	}
	queue<int> q;q.push(S);
	dep[S]=1;
	while(q.size()){
		int u=q.front();q.pop();
		for(int i=h[u];i;i=ne[i]){
			int v=to[i];
			if(w[i]&&dep[v]==-1){
				dep[v]=dep[u]+1;
				q.push(v);
			}
		}
	}
	//cout<<(dep[T]!=-1)<<"\n";
	return dep[T]!=-1;
}
int dfs(int u,int pre){
	if(u==T) return pre;
	int ans=0;
	for(int i=cur[u];i&&pre;i=ne[i]){
		int v=to[i];
		cur[u]=i;
		if(w[i]&&dep[u]+1==dep[v]){
			int res=dfs(v,min(pre,w[i]));
			ans+=res;
			w[i]-=res;
			w[i^1]+=res;
			pre-=res;
		}
	}
	if(ans==0) dep[u]=-1;
	return ans;
}
int Dinic(){
	int res=0;
	while(bfs()){
		//puts("@");
		res+=dfs(S,inf);
	}
	return res;
}
int solve(int tp){
	int ans=0;
	if(!mp[tp][tp]) ans++;
	for(int i=1;i<=n;i++){
		if(tp==i) continue;
		ans+=(!mp[tp][i])+(!mp[i][tp]);
	}
	
	for(int i=S;i<=T;i++){
		h[i]=0;
	}
	idx=1;
	int cnt=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==tp||j==tp) continue;
			if(mp[i][j]){
				cnt++;
				add(i,j+n,1);
			}
		}
	}
	
	for(int i=1;i<=n;i++){
		if(i==tp) continue;
		add(S,i,1);
		add(i+n,T,1);
	}
	int k=Dinic();
	//cout<<ans<<" "<<(n-1)*2<<" "<<k*2<<"\n";
	ans+=cnt-k;
	ans+=n-1-k;
 	return ans;
}
signed main(){
	cin>>n>>m;
	T=n+n+1;
	for(int i=1;i<=m;i++){
		int a,b;cin>>a>>b;
		mp[a][b]=1;
	}
	int ans=inf;
	for(int i=1;i<=n;i++){
		ans=min(ans,solve(i));
	}
	cout<<ans<<"\n";
	return 0;
}
posted @ 2026-06-26 20:03  Aistyr  阅读(5)  评论(0)    收藏  举报