• [20200721省选B模拟T3]匹配


    题目链接:

      P3967 [TJOI2014]匹配

    题目大意:

      给定n男n女,n男与n女两两之间有一个幸福值H[i][j],请求出他们之间的完美匹配并且输出匹配的必须边的端点.($nleq80$)

    solution:

       对于完美匹配,我们可以跑最大费用最大流.至于求必须边,不难发现第一次跑完完美匹配后,男女点之间只流过了n条边,所以剩余的边肯定不是必须边.由于n值较小,所以我们可以一一枚举第一次费用流所流过的边,断边观察最大费用是否改变,若改变则统计答案即可.

    code:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #define R register
    #define next exnttttttttttttttttttttt
    #define debug puts("mlg")
    using namespace std;
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    inline ll read();
    inline void write(ll x);
    inline void writesp(ll x);
    inline void writeln(ll x);
    ll n,S,T;
    ll H[88][88];
    ll to[50000],from[50000],head[50000],next[50000],tot=1,c[50000],w[50000];
    inline void add(ll x,ll y,ll u,ll v){
        to[++tot]=y;from[tot]=x;next[tot]=head[x];head[x]=tot;c[tot]=u;w[tot]=v;
    }
    ll d[50000],last[50000],incf[50000],pre[50000];
    bool vis[50000];
    queue<ll>q;
    inline bool spfa(){
        for(R ll i=1;i<=T;i++) d[i]=-1000000;
        memset(vis,0,sizeof vis);
        while(q.size())q.pop();
        incf[S]=12534567984654089;
        d[S]=0;
        q.push(S);pre[T]=-1;
        while(!q.empty()){
            ll x=q.front();q.pop();vis[x]=false;
            for(R ll i=head[x],ver;i;i=next[i]){
                ver=to[i];
                if(!c[i]) continue;
                if(d[ver]<d[x]+w[i]){
                    d[ver]=d[x]+w[i];
                    incf[ver]=min(incf[x],c[i]);
                    last[ver]=i;
                    pre[ver]=x;
                    if(!vis[ver]){
                        vis[ver]=true;
                        q.push(ver);
                    }
                }
            }
        }
        return d[T]!=-1000000;
    }
    ll ans,maxflow;
    inline void update(){
        ll x=T;
        while(x!=S){
            c[last[x]]-=incf[T];
            c[last[x]^1]+=incf[T];
            x=pre[x];
        }
        ans+=d[T]*incf[T];
        maxflow+=incf[T];
    }
    ll TOT,D[5000];
    bool check[90][90];
    int main(){
        freopen("match.in","r",stdin);
        freopen("match.out","w",stdout);
        n=read();
        for(R ll i=1;i<=n;i++){
            for(R ll j=1;j<=n;j++){
                H[i][j]=read();
            }
        }
        S=n*2+1,T=S+1;
        for(R ll i=1;i<=n;i++){
            add(S,i,1,0);add(i,S,0,0);
            add(i+n,T,1,0);add(T,i+n,0,0);
        }
        for(R ll i=1;i<=n;i++){
            for(R ll j=1;j<=n;j++){
                add(i,j+n,1,H[i][j]);
                add(j+n,i,0,-H[i][j]);
            }
        }
        while(spfa()) update();
        writeln(ans);
        ll Ans=ans;
        for(R ll i=2;i<tot;i+=2){
            if(!c[i]&&from[i]!=S&&to[i]!=T) D[++TOT]=i;
            c[i]+=c[i^1];c[i^1]=0;
        }
        for(;TOT;--TOT){
            for(R ll i=2;i<tot;i+=2) c[i]+=c[i^1],c[i^1]=0;
            ll C=c[D[TOT]];c[D[TOT]]=0,ans=0;
            while(spfa()) update();
            if(Ans!=ans){
                check[from[D[TOT]]][to[D[TOT]]-n]=true;
            }
            c[D[TOT]]+=C;
        }
        for(R ll i=1;i<=n;i++){
            for(R ll j=1;j<=n;j++) if(check[i][j]) writesp(i),writeln(j);
        }
    }
    inline ll read(){
        ll x=0,t=1;char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-') t=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*t;
    }
    inline void write(ll x){
        if(x<0){putchar('-');x=-x;}
        if(x<=9){putchar(x+'0');return;}
        write(x/10);putchar(x%10+'0');
    }
    inline void writesp(ll x){
        write(x);putchar(' ');
    }
    inline void writeln(ll x){
        write(x);putchar('
    ');
    }
  • 相关阅读:
    yum 崩溃的解决方法
    线上mysql数据库删库恢复的案例
    CVE-2018-8120 WIN7 08提权漏洞exp
    CVE-2018-1111 劫持dhcp造成Redhat、centos代码执行
    关于 Python generator(生成器)的类比
    黯淡蓝点:旅行者号64亿公里外回望地球...
    raise RuntimeError("autoconf error") RuntimeError: autoconf error
    python 调取 shell 命令的几种方法
    struct 处理二进制
    linux 下日常使用便利工具
  • 原文地址:https://www.cnblogs.com/ylwtsq/p/13355680.html
Copyright © 2020-2023  润新知