cf387 D. George and Interesting Graph(思维+二分图)

31 篇文章 0 订阅
13 篇文章 2 订阅

传送门

题意

给定一个有向图,每次操作可以随意添加或删除任一条边。求让该无向图满足:

1. 1. 1. 存在一个中心点 v v v(自由指定),从该点到其他任一一点 u u u 都存在边 ( v , u )   ( u , v ) (v,u)\ (u,v) (v,u) (u,v),并且该点存在自环。

2. 2. 2. 除中心点外的所有点,出度和入度均为 2 2 2

所需要的最少操作次数。


在确定了中心点之后,去掉该中心点及所有与该点有关的边,剩下的所有点的出度和入度均为 1,则此时剩下的图是由若干个环组成。

鉴于此时所有点入边和出边的唯一性,考虑将所有点拆分为入点和出点,所有入点在左集合,所有出点在右集合。将所有的边载入该二分图后,最大匹配数即为可以保留的边,其余需要删除。对于未被匹配到的 孤 寡 点 数 目 / 2 孤寡点数目/2 /2 ,即为需要加入的边数。

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int INF = 0x3fffffff;
const int N=550;
int g[N][N];
int gg[N][N];
int vis[N],match[N];
int n,m;

int find(int u){
	for(int i=1;i<=n;i++){
		if(!vis[i]&&gg[u][i]){
			vis[i]=true;
			if(match[i]==-1||find(match[i])){
				match[i]=u;
				return 1;
			}
		}
	}
	return 0;
}

signed main(){
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int u,v;
		cin>>u>>v;
		g[u][v]=1;
	}
	int ret=INF;
	for(int i=1;i<=n;i++){
		int use=0;
		int ans=0;
		for(int j=1;j<=n;j++){
			if(i==j){//自环 
				if(!g[i][j]) 
					ans++;
				else
					use++;
			}
			else{
				if(!g[i][j]) 
					ans++;
				else 
					use++;
					
				if(!g[j][i]) 
					ans++;
				else 
					use++;
			}
		}
		memset(match,-1,sizeof(match));
		memcpy(gg,g,sizeof(gg));
		for(int j = 0;j<=n;j++) 
			gg[i][j]=gg[j][i]=0;
		int x=0;
		for(int k=1;k<=n;k++){
			memset(vis,0,sizeof(vis));
			if(find(k)) 
				x++;
		}
		use+=x;
		int left=n-1-x;
		ret=min(ret,m-use+ans+left);
	}
	cout<<ret<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值