zoukankan      html  css  js  c++  java
  • 「伪模板」主席树(最大流)

    「伪模板」主席树

    果然,题目显示什么算法就绝对和什么算法没关系...

    这个题建图挺显然的吧....

    这里重新思考一下建图的意义:源点向某个点连边表示某个点本来就有的属性,某个点向汇点连边,表示这个点向答案能造成的贡献和限制.

    之后就是两侧的点连边...

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=210,M=N*N*2,INF=1e9;
    int link[N],tot=1,n,m,id1[N],id2[N],blood1[N],blood2[N],s,t;
    int current[N],d[N];
    struct edge{int y,v,next;}a[M];
    char c[10];
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline void add(int x,int y,int v)
    {
        a[++tot].y=y;a[tot].v=v;a[tot].next=link[x];link[x]=tot;
        a[++tot].y=x;a[tot].v=0;a[tot].next=link[y];link[y]=tot;
    }
    inline  void init()
    {
        for(int i=1;i<=n;++i) 
        {
            scanf("%s",c);
            if(c[0]=='W') id1[i]=1;
            else if(c[0]=='J') id1[i]=2;
            else if(c[0]=='E') id1[i]=3;
            else if(c[0]=='Y') id1[i]=4;
            else if(c[0]=='H') id1[i]=5;
        }
        for(int i=1;i<=n;++i) 
        {
            scanf("%s",c);
            if(c[0]=='W') id2[i]=1;
            else if(c[0]=='J') id2[i]=2;
            else if(c[0]=='E') id2[i]=3;
            else if(c[0]=='Y') id2[i]=4;
            else if(c[0]=='H') id2[i]=5;
        }
        for(int i=1;i<=n;++i) blood1[i]=read();
        for(int i=1;i<=n;++i) blood2[i]=read();
    }
    inline void make_chart()
    {
        s=0;t=n<<1|1;
        int cnt=0;
        for(int i=1;i<=n;++i) if(id1[i]==4) cnt++;
        for(int i=1;i<=n;++i) if(id1[i]==2) blood1[i]+=cnt;
        for(int i=1;i<=n;++i) add(s,i,blood1[i]);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                if(id1[i]==1&&(id2[j]==3||id2[j]==4)) add(i,j+n,1);    
                else if(id1[i]==2&&(id2[j]==1||id2[j]==5)) add(i,j+n,1);
                else if(id1[i]==3&&(id2[j]==2||id2[j]==4)) add(i,j+n,1);
                else if(id1[i]==4&&(id2[j]==2||id2[j]==5)) add(i,j+n,1);
                else if(id1[i]==5&&(id2[j]==3||id2[j]==1)) add(i,j+n,1);
            }
        cnt=0;
        for(int i=1;i<=n;++i) if(id2[i]==4) cnt++;
        for(int i=1;i<=n;++i) if(id2[i]==2) blood2[i]+=cnt;
        for(int i=1;i<=n;++i) add(i+n,t,blood2[i]);
    }
    inline bool bfs()
    {
        queue<int>q;q.push(s);
        memset(d,0,sizeof(d));
        memcpy(current,link,sizeof(current));
        d[s]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=link[x];i;i=a[i].next)
            {
                int y=a[i].y;
                if(d[y]||!a[i].v) continue;
                d[y]=d[x]+1;
                q.push(y);
                if(y==t) return true;
            }
        }
        return false;
    }
    inline int dinic(int x,int flow)
    {
        if(x==t) return flow;
        int rest=flow,k;
        for(int i=current[x];i&&rest;i=a[i].next)
        {
            current[x]=i;
            int y=a[i].y;
            if(d[y]==d[x]+1&&a[i].v)
            {
                k=dinic(y,min(a[i].v,rest));
                if(!k) d[y]=0;
                a[i].v-=k;
                a[i^1].v+=k;
                rest-=k;
            }
        }
        return flow-rest;
    }
    int main()
    {
        freopen("1.in","r",stdin);
        n=read();m=read();
        init();
        make_chart();
        int maxflow=0,flow;
        while(bfs())
            while(flow=dinic(s,INF)) maxflow+=flow;
        printf("%d",maxflow>m?m:maxflow);
        return 0;    
    }
    View Code
  • 相关阅读:
    AtCoder Beginner Contest 205
    Codeforces Round #725 (Div. 3)
    Educational Codeforces Round 110 (Rated for Div. 2)【A
    Codeforces Round #722 (Div. 2)
    AtCoder Beginner Contest 203(Sponsored by Panasonic)
    AISing Programming Contest 2021(AtCoder Beginner Contest 202)
    PTA 520 钻石争霸赛 2021
    Educational Codeforces Round 109 (Rated for Div. 2)【ABCD】
    AtCoder Beginner Contest 200 E
    Educational Codeforces Round 108 (Rated for Div. 2)【ABCD】
  • 原文地址:https://www.cnblogs.com/gcfer/p/12536795.html
Copyright © 2011-2022 走看看