[八省联考2018]劈配

题解:

这题思路就是暴力。。 主要在于分析复杂度?

Dinic跑二分图$msqrt(n)$ 这题好像用不到。。

首先这是个匹配问题显然需要利用网络流

考虑第一问

每一次我们就暴力按照志愿顺序加入边

直到二分图匹配数+1

这个复杂度是$(nm)*nm$的(因为一次只增广一条边所以每次是nm的,不过这个很明显是跑不满而且差挺多的)

这样比较gg,我们注意到有用的边只有C条

大概是$(nm/c)*cn$ 也就是n^2m的(我这个复杂度假设了c相同)

(洛谷上的题解说是$n^2c$的 感觉不太对。。)

考虑第二问

首先肯定要二分答案

然后在残余网络上继续跑(记录n个残余网络)

时间复杂度$nlogn*nc$

总时间复杂度$n^2(clogn+m)$

这题交上去70。。

查错查的心态爆炸

多组数据就炸单组数据就过

然后以为是没清空什么东西。。

后来发现是 还原的时候我的还原顺序不对导致还原了上一次的答案

而由于这个还原不还原也是对的,所以单组数据没炸

***还原的时候要逆序还原

***memset还可以清空自定义类型??

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register int
#define IL inline
#define rep(i,h,t) for(int i=h;i<=t;i++)
#define dep(i,t,h) for(int i=t;i>=h;i--)
#define ll long long
#define me(x) memset(x,0,sizeof(x))
#define mep(x,y) memcpy(x,y,sizeof(y))
#define mid ((h+t+1)>>1)
namespace IO{
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
        return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T> void read(T &x)
    {
        rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
        while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f; 
    }
    char sr[1<<24],z[20]; int Z,C1=-1;
    template<class T>void wer(T x)
    {
        if (x<0) sr[++C1]='-',x=-x;
        while (z[++Z]=x%10+48,x/=10);
        while (sr[++C1]=z[Z],--Z);
    }
    IL void wer1()
    {
        sr[++C1]=' ';
    }
    IL void wer2()
    {
        sr[++C1]='
';
    }
    template<class T>IL void maxa(T &x,T y) {if (x<y) x=y;}
    template<class T>IL void mina(T &x,T y) {if (x>y) x=y;} 
    template<class T>IL T MAX(T x,T y){return x>y?x:y;}
    template<class T>IL T MIN(T x,T y){return x<y?x:y;}
};
using namespace IO;
const int INF=1e9;
const int N=300;
int T,c,n,m,a[N],f[N][N],s,t,se[N],ans[N],ans2[N];
vector<int> ve[N][N];
const int M=450;
const int M2=6000;
struct re{
    int a,b,c,flow;
}jl[M2];
int cnt1=0; 
struct Dinic{
    int head[M],head2[M],d[M],l,flow;
    re e[M2];
    IL void arr(int x,int y,int z)
    {
        e[++l].a=head[x];
        e[l].b=y;
        e[l].c=z;
        e[l].flow=0;
        jl[++cnt1]=(re){x,head[x]};
        head[x]=l;
    }
    IL void arr2(int x,int y,int z)
    {
        arr(x,y,z); arr(y,x,0);
    }
    bool bfs()
    {
        rep(i,1,t) d[i]=INF;
        d[s]=0;
        queue<int> q;
        q.push(s);
        while (!q.empty())
        {
            int x=q.front(); q.pop();
            for (int u=head[x];u;u=e[u].a)
            {
                int v=e[u].b;
                if (d[v]==INF&&e[u].c>e[u].flow)
                  d[v]=d[x]+1,q.push(v);
            }        
        }
        if (d[t]==INF) return(0); else return(1);
    }
    int dfs(int x,int y)
    {
        if (x==t||!y) return(y);
        int f,flow=0;
        for (rint u=head[x];u;u=e[u].a)
        {
            int v=e[u].b;
            if (d[v]==d[x]+1&&(f=dfs(v,MIN(y,e[u].c-e[u].flow)))>0)
            {
                flow+=f; y-=f;
                e[u].flow+=flow;
                if (u%2==1) e[u+1].flow-=flow;
                else e[u-1].flow-=flow;
            }
            if (!y) break;
            head[x]=u;
        }
        return flow;
    }
    void maxflow()
    {
        mep(head2,head);
        while (bfs())
        {
            flow+=dfs(s,INF);
            mep(head,head2);
        }
    }
}D[202],now;
IL void fz(Dinic &a,Dinic &b)
{
    mep(a.head,b.head);
    mep(a.e,b.e);
    a.l=b.l; a.flow=b.flow;
}
IL bool check(int x,int y)
{
    fz(now,D[y]);
    rep(i,1,se[x])
    {
        int l=ve[x][i].size();
        for (int j=0;j<l;j++)
          now.arr2(x,ve[x][i][j]+n,1);
    }
    now.maxflow();
    if (now.flow==D[y].flow+1) return(1);
    else return(0);
}
int main()
{
    read(T); read(c);
    rep(ttt,1,T)
    {
        read(n); read(m);
        rep(i,1,m) read(a[i]);
        rep(i,1,n)
        {
          rep(j,1,m) ve[i][j].clear();
          rep(j,1,m)
          {
            read(f[i][j]);
            if (f[i][j]) ve[i][f[i][j]].push_back(j); 
          }
        }
        rep(i,1,n) read(se[i]);
        s=0; t=n+m+1;
        D[0].l=0; me(D[0].head);
        rep(i,1,n)
          D[0].arr2(s,i,1);
        rep(i,1,m)
          D[0].arr2(i+n,t,a[i]);
        rep(i,1,n)
        {    
          ans[i]=m+1;
          fz(D[i],D[i-1]);
          int tmp=D[i].l;
          cnt1=0;
          rep(j,1,m)
          {
              dep(k,cnt1,1) D[i].head[jl[k].a]=jl[k].b;
            int l=ve[i][j].size(); D[i].l=tmp;
            cnt1=0;
            for (int k=0;k<l;k++)
              D[i].arr2(i,ve[i][j][k]+n,1);
            D[i].maxflow();
            if (D[i].flow==D[i-1].flow+1)
            { 
              ans[i]=j; break;
            }
          }
        }
        rep(i,1,n)
        {
            ans2[i]=0;
            if (ans[i]>se[i])
            {
                int h=0,t=i-1;
                while (h<t)
                {
                    if (check(i,mid)) h=mid; else t=mid-1;
                }
                if (!check(i,h)) ans2[i]=i;
                else ans2[i]=i-h-1;
            }
        }
        rep(i,1,n) wer(ans[i]),wer1();
        wer2();
        rep(i,1,n) wer(ans2[i]),wer1();
        wer2();
    }
    fwrite(sr,1,C1+1,stdout);
    return 0;
}
原文地址:https://www.cnblogs.com/yinwuxiao/p/10039482.html