【题解】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&⪯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;
}

浙公网安备 33010602011771号