zoukankan      html  css  js  c++  java
  • BZOJ5251: [2018多省省队联测]劈配

    BZOJ5251: [2018多省省队联测]劈配

    https://lydsy.com/JudgeOnline/problem.php?id=5251

    分析:

    • 这是个水题啊,就是题面太长。
    • 首先要知道这样一件事:
    • 我们建图跑dinic之后若再加一些边跑一次,如果最大流增加,那么一定有新的匹配。
    • 这就意味着不会出现新加的点匹配到了,之前的点却被修改成无匹配状态。
    • 然后按题意模拟即可,第一问直接做,第二问二分。
    • 由于写不明白撤销刚加的边,我每次做的时候都重新建图。

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    using namespace std;
    #define N 405
    #define S 403
    #define T 404
    #define M 1000050
    #define inf 0x3f3f3f3f
    int head[N],to[M],nxt[M],flow[M],cnt,n,m,b[N];
    int dep[N],Q[N],ans1[N],ans2[N],a[N][N],s[N];
    vector<int>V[205][205];
    inline void add(int u,int v,int f) {
        to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; flow[cnt]=f;
        to[++cnt]=u; nxt[cnt]=head[v]; head[v]=cnt; flow[cnt]=0;
    }
    bool bfs() {
        memset(dep,0,sizeof(dep)); dep[S]=1;
        int l=0,r=0;
        Q[r++]=S;
        while(l<r) {
            int x=Q[l++],i;
            for(i=head[x];i;i=nxt[i]) if(!dep[to[i]]&&flow[i]) {
                dep[to[i]]=dep[x]+1; if(to[i]==T) return 1;
                Q[r++]=to[i];
            }
        }
        return 0;
    }
    int dfs(int x,int mf) {
        if(x==T) return mf;
        int i,nf=0;
        for(i=head[x];i;i=nxt[i]) if(dep[to[i]]==dep[x]+1&&flow[i]) {
            int tmp=dfs(to[i],min(mf-nf,flow[i]));
            if(!tmp) dep[to[i]]=0;
            flow[i]-=tmp, flow[i^1]+=tmp, nf+=tmp;
            if(nf==mf) break;
        }
        return nf;
    }
    void dinic() {while(bfs()) while(dfs(S,inf)>0);}
    void solve() {
        scanf("%d%d",&n,&m);
        int i,j,k;
        for(i=1;i<=m;i++) scanf("%d",&b[i]);
        for(i=1;i<=n;i++) for(j=0;j<=m+1;j++) V[i][j].clear();
        memset(ans1,0,sizeof(ans1));
        memset(ans2,0,sizeof(ans2));
        for(i=1;i<=n;i++) {
            for(j=1;j<=m;j++) {
                scanf("%d",&a[i][j]);
                if(a[i][j]) V[i][a[i][j]].push_back(j);
            }
        }
        for(i=1;i<=n;i++) scanf("%d",&s[i]);
        for(i=1;i<=n;i++) {
            memset(head,0,sizeof(head)); cnt=1;
            for(j=1;j<=i;j++) add(S,j,1);
            int bvb=cnt;
            for(j=1;j<=m;j++) add(j+n,T,b[j]);
            for(j=1;j<i;j++) {
                int lim=V[j][ans1[j]].size();
                for(k=0;k<lim;k++) add(j,V[j][ans1[j]][k]+n,1);
            }
            dinic();
            for(j=1;j<=m;j++) {
                int lim=V[i][j].size();
                if(!lim) continue;
                for(k=0;k<lim;k++) {
                    add(i,V[i][j][k]+n,1);
                }
                dinic();
                if(flow[bvb]==1) {
                    ans1[i]=j; break;
                }
            }
            if(!ans1[i]) ans1[i]=m+1;
        }
        for(i=1;i<=n;i++) printf("%d ",ans1[i]); puts("");
        for(i=1;i<=n;i++) {
            if(ans1[i]<=s[i]) continue;
            int l=1,r=i;
            while(l<r) {
                int mid=(l+r)>>1;
                memset(head,0,sizeof(head)); cnt=1;
                int ni=i-mid;
                for(j=1;j<ni;j++) add(S,j,1);
                for(j=1;j<=m;j++) add(j+n,T,b[j]);
                add(S,i,1);
                int bvb=cnt;
                for(j=1;j<ni;j++) {
                    int lim=V[j][ans1[j]].size();
                    for(k=0;k<lim;k++) add(j,V[j][ans1[j]][k]+n,1);
                }
                dinic();
                for(j=1;j<=s[i];j++) {
                    int lim=V[i][j].size();
                    for(k=0;k<lim;k++) add(i,V[i][j][k]+n,1);
                }
                dinic();
                if(flow[bvb]==1) r=mid;
                else l=mid+1;
            }
            ans2[i]=l;
        }
        for(i=1;i<=n;i++) printf("%d ",ans2[i]); puts("");
    }
    int main() {
        int cas;
        scanf("%d%*d",&cas);
        while(cas--) solve();
    }
    
  • 相关阅读:
    工业相机基础知识
    软件测试最常用的 SQL 命令 | 掌握基本查询、条件查询、聚合查询
    一文掌握软件测试常用SQL命令
    PageObject设计模式在 UI 自动化中的实践(QQ 邮箱登陆为例)
    测试开发必备--搞定PO设计模式
    Junit5 + YAML 参数化和数据驱动,让 App 自动化测试更高效(一)
    快速搞定APP移动端自动化测试
    接口自动化测试的 “能” 与 “不能”
    如何精通接口测试?
    测试开发必备:Dubbo-admin+Zookeeper 的环境搭建实操
  • 原文地址:https://www.cnblogs.com/suika/p/10051103.html
Copyright © 2011-2022 走看看