zoukankan      html  css  js  c++  java
  • Codeforces434D 网络流

    思路:
    题意:有n<=50个点,每个点有xi有[li, ri]种取值,-100 <= li <= ri <= 100,并且给定m<=100条边,每条边为u,v,d表示xu<=xv+d。

        每个点value fi(x) = ai*x^2 + bi*x + ci。现在求一种合法的方案,使得权值和最大。
    

    思路:先不考虑的xu<=xv + d。那么建图:

       首先考虑到每个点的权值可能为负,并且求最大与最小割相反,
    
        所以先 取反再+oo(一个很大的数),最后再减掉即可
    
        对于每个点,拆成ri-li+1个点,
    
        对于第k个点,node(k, i)表示第k个点值为i对应的标号
    
        值为i-1跟i连一条边<node(k, i-1), node(k, i),  oo - f(k, i)>的边,
    
        S到第一个点连<S, node(k, l[k]), f(k, l[k])>
    
       最后一个点到T连<node(k,r[k]), Inf>
    
       那么很明显n*oo-最小割就是答案。。
    
       但是如果有了限制条件xu<=xv + d,我们怎么把限制条件加到图上呢?
    
       对于一对关系,xu<=xv+d
    
       考虑到点u,如果node(u, i)到node(u,i+1)之间的边在割集里,那么说明xu=i+1
    
       也就是说如果xv<xu-d是非法的,也就是说对于v在xu-d之前出现割是非法的。
    
       那么我们可以连<node(u,i), node(v, i-d), Inf>的边,使得方案合法。。
    

    from http://www.cnblogs.com/yzcstc/p/4062097.html

    //By SiriusRen
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 111
    #define maxn 11111
    #define M 88888
    #define inf 0x3f3f3f3f
    int n,m,a[N],b[N],c[N],l[N],r[N],id[N][N*2],cnt,maxx=-inf,ed=11100;
    int first[maxn],vis[maxn],v[M],w[M],nxt[M],tot,U,V,D,jy,ans;
    int func(int x,int y){return a[x]*y*y+b[x]*y+c[x];}
    void Add(int x,int y,int z){w[tot]=z,v[tot]=y,nxt[tot]=first[x],first[x]=tot++;}
    void add(int x,int y,int z){Add(x,y,z),Add(y,x,0);}
    bool tell(){
        memset(vis,-1,sizeof(vis)),vis[0]=0;
        queue<int>q;q.push(0);
        while(!q.empty()){
            int t=q.front();q.pop();
            for(int i=first[t];~i;i=nxt[i])
                if(w[i]&&vis[v[i]]==-1)
                    vis[v[i]]=vis[t]+1,q.push(v[i]);
        }
        return vis[ed]!=-1;
    }
    int zeng(int x,int y){
        if(x==ed)return y;
        int r=0;
        for(int i=first[x];~i&&y>r;i=nxt[i])
            if(w[i]&&vis[v[i]]==vis[x]+1){
                int t=zeng(v[i],min(w[i],y-r));
                w[i]-=t,w[i^1]+=t,r+=t;
            }
        if(!r)vis[x]=-1;
        return r;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i],&b[i],&c[i]);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&l[i],&r[i]);
            for(int j=l[i];j<=r[i];j++)
                maxx=max(maxx,func(i,j));
        }
        maxx++;
        memset(first,-1,sizeof(first));
        for(int i=1;i<=n;i++){
            for(int j=l[i];j<=r[i]+1;j++)id[i][j+100]=++cnt;
            for(int j=l[i];j<=r[i];j++)add(id[i][j+100],id[i][j+101],maxx-func(i,j));
            add(0,id[i][l[i]+100],inf),add(id[i][r[i]+101],ed,inf);
        }
        for(int i=1;i<=m;i++) {
            scanf("%d%d%d",&U,&V,&D);
            for(int j=l[U];j<=r[U]+1;j++)
                if(j-D>=l[V]&&j-D<=r[V]+1)add(id[U][j+100],id[V][j-D+100],inf);
        }
        while(tell())while(jy=zeng(0,inf))ans+=jy;
        printf("%d
    ",maxx*n-ans);
    }

    这里写图片描述

  • 相关阅读:
    Android AlertDialog警告对话框实现
    Android状态栏通知Status Bar Notification
    Android spinner控件的实现
    Winform之UI后台线程
    Winform之自定义控件
    WebForm原理,aspx服务器端与客户端源码比较
    IHttpModule之闲扯
    [算法]方正面试题:N×N矩阵螺旋打印输出
    DOTA版设计模式——工厂方法
    Window服务
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532115.html
Copyright © 2011-2022 走看看