题解 CF387D 【George and Interesting Graph】

· · 题解

唔姆

一道十分因缺思厅的题

放上我巨丑无比的代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define MAXN 11050
#define MAXM 150005
using namespace std;
int head[MAXN],nextt[MAXM*2],to[MAXM*2],w[MAXM*2];
int n,m,S,T;
int cnt=-1;
int deep[MAXN];
struct line{
       int from;
       int to;
}l[MAXM];
void link(int a,int b,int c){
     cnt++;
     w[cnt]=c;
     nextt[cnt]=head[a];
     to[cnt]=b;
     head[a]=cnt;
     cnt++;
     w[cnt]=0;
     nextt[cnt]=head[b];
     to[cnt]=a;
     head[b]=cnt;
}
bool bfs(){
     memset(deep,0,sizeof(deep));
     queue<int> q;
     while(!q.empty())q.pop();
     q.push(S);
     deep[S]=1;
     while(!q.empty()){
                       int now=q.front();
                       q.pop();
                       for(int i=head[now];i!=-1;i=nextt[i]){
                               if (w[i]&&!deep[to[i]]){
                                                       deep[to[i]]=deep[now]+1;
                                                       q.push(to[i]);
                               }
                       }
     }
     if (deep[T])return 1;else return 0;
}
int dinic(int now,int last){
    if (now==T||!last)return last;
    int ret=0;
    for(int i=head[now];i!=-1;i=nextt[i]){
            if(deep[to[i]]-1==deep[now]&&w[i]){
                                               int zgl=dinic(to[i],min(w[i],last-ret));
                                               if (zgl){
                                                        w[i]-=zgl;
                                                        w[i^1]+=zgl;     
                                                        ret+=zgl;
                                               }
            }
    }
    if (!ret)deep[now]=-1;
    return ret;
}
int into[MAXN],out[MAXN];
int main(){
    cin>>n>>m;
    S=0;T=MAXN-1;
    memset(into,0,sizeof(into));
    int a,b;
    for(int i=1;i<=m;i++){
            scanf("%d%d",&a,&b);
            l[i].from=a;l[i].to=b;
            into[b]++;
            out[a]++;
            if (a==b)into[b]--;
    }
    int anss=MAXM;
    for(int i=1;i<=n;i++){
            memset(head,-1,sizeof(head));
            cnt=-1;
            int tmp=into[i]+out[i];
            for(int j=1;j<=n;j++){
                    link(S,j,1);
                    link(j+500,T,1);
            }
            for(int j=1;j<=m;j++){
                    if (l[j].to==i||l[j].from==i)continue;
                    link(l[j].from,l[j].to+500,1);
            }
            int ans=0;        
            while(bfs())
                        ans+=dinic(S,9999999);
            anss=min(anss,n-1-ans+m-ans+2*n-1-tmp*2);
    }
    cout<<anss<<endl;
    return 0;
}