zoukankan      html  css  js  c++  java
  • BZOJ 2163 复杂的大门

    题目传送门

    分析:

    这个好像和那道清理滑雪跑道好像啊。。。

    如果每个点都要访问恰好Fi次

    然后边不能超过w次

    哦。。。

    上下界网络流

    每个点拆成两个,原点向复制点连上(F,F)的边,复制点向可到达的原点连(0,w)的边

    由于公交可以到达每个点,相当于发配流量,每个点都可以停下,相当于直接流向终点

    所以S向每个原点连(0,INF)的边,每个复制点向T连(0,INF)的边

    然后直接跑就好了。。。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    
    #define maxn 20005
    #define maxm 2000005
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    inline int getint()
    {
        int num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    int n,m,S,T;
    int fir[maxn],nxt[maxm],to[maxm],cap[maxm],cnt;
    int h[maxn],tp[maxn];
    int f[maxn];
    long long ans;
    
    inline void newnode(int u,int v,int w)
    {to[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt,cap[cnt]=w;}
    inline void insert(int u,int v,int w)
    {newnode(u,v,w),newnode(v,u,0);}
    
    inline bool bfs()
    {
        memset(h,-1,sizeof h);
        queue<int>Q;h[S]=0,Q.push(S);
        while(!Q.empty())
        {
            int u=Q.front();Q.pop();
            for(int i=fir[u];i;i=nxt[i])
                if(cap[i]&&!~h[to[i]])h[to[i]]=h[u]+1,Q.push(to[i]);
        }
        return ~h[T];
    }
    
    inline int dfs(int u,int flow)
    {
        if(u==T)return flow;
        int used=0;
        for(int i=tp[u];i;i=nxt[i])
        {
            tp[u]=i;
            if(cap[i]&&h[to[i]]==h[u]+1)
            {
                int w=flow-used;
                w=dfs(to[i],min(cap[i],w));
                cap[i]-=w,cap[i^1]+=w,used+=w;
                if(used==flow)return flow;
            }
        }
        if(!used)h[u]=-1;
        return used;
    }
    
    inline int dinic()
    {
        int num=0;
        while(bfs())memcpy(tp,fir,sizeof fir),num+=dfs(S,INF);
        return num;
    }
    
    int main()
    {
        n=getint(),m=getint();
        S=2*n+1,T=S+1;cnt=1;
        for(int i=1;i<=n;i++)
        {
            int x=getint();
            f[i]-=x,f[i+n]+=x;
            insert(S,i,50000),insert(i+n,T,50000);
        }
        for(int i=1;i<=m;i++)
        {
            int u=getint(),v=getint(),w=getint();
            insert(u+n,v,w);
        }
        int SS=T+1,TT=SS+1;
        for(int i=1;i<=T;i++)
            if(f[i]>0)insert(SS,i,f[i]);
            else insert(i,TT,-f[i]);
        insert(T,S,INF);
        S=SS,T=TT;
        dinic();
        printf("%d
    ",cap[cnt]);
    }
    View Code

  • 相关阅读:
    React:Target container is not a DOM element
    安装完node.js,在命令行输入npm -v无反应的解决办法
    正则匹配中文字符
    设计一个函数,它接受不定数量的参数,这是参数都是函数。这些函数都接受一个回调函数作为参数,按照回调函数被调用的顺序返回函数名
    回调函数/callback
    切图 or 切片
    编写获取最终样式的函数
    【Java例题】5.2 数组转换
    【Java例题】5.1 多项式计算
    【Java例题】4.5异常处理
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12013570.html
Copyright © 2011-2022 走看看