[上下界费用流]JZOJ 3302 供电网络

Description

阿狸和桃子居住的世界里, 只有一个国家, 这个国家有很多城市, 每个城市直接由中央政府管辖.
电力是这个国家的唯一能源, 但是每个城市的发电能力都不一样, 于是就产生了某些城市电力不足, 而某些城市却电力过剩的情况.
阿狸作为国家的首席工程师, 阿狸的一项重要工作就是均衡整个国家的电力, 使得每个城市的电力都恰好没有剩余或不足.
好在一些城市之间有电线可以输送电力, 这些电线都有自己的输送上限和下限, 并且输送电力的同时会产生大量的热.
每条电线i 发出的热量一定是关于输送电量的一个没有常数项的二次函数,即a_i*x^2+b_i*x, 并且由于电线是二极管做成的, 很显然只能单向输送电力. 每单位热量需要用1 单位的金币来冷却. 任何两个城市之间, 至多有一条电线.
不幸的是, 有时电力网络不像我们想的那么完美, 某些情况下可能无论如何都不能满足整个国家的电力需求. 这种情况下就只好向别的世界购买电力或者将电力输出给别的世界(注意, 每个城市的电力不能有剩余!), 每个城市买入或者输出电力的价格是不一样的(输出也要花钱).
由于阿狸的国家没有小数的概念, 输送,、购买或者交换电力都必须是以整数1 为单位.
阿狸的任务是最小化金币的花费(买入/送出的费用+电线上发热的冷却费用),他最近被这个问题搞得焦头烂额, 以至于没有时间去陪桃子玩, 结果天天被桃子骂T_T. 好在有你, 万能的程序猿, 请你编写一个程序来帮阿狸解决这个问题吧.

Input

第一行2 个整数, n 和m, 分别是城市个数和有向电线条数.
接下来n 行, 每行3 个整数[left, in, out], 其中第k 行表示第k 个城市的信息:
left 表示这个城市剩余(负数为不足)的电量, -5 <= left <= 5.
in, out 表示这个城市买入或送出一个单位电量的价格. 0 <= in, out <= 10000
最后m 行, 每行6 个整数, u, v, a, b, L, U 其中第k 行表示第k 条电线的信息:
u, v 分别表示电线的开始和结束城市(电力只能从u 输送到v).
a, b 表示电线发热的二次函数的二次项和一次项.
L, U 表示电线输送电力的下界和上界.

Output

仅一个整数, 表示最小的金币花费.

Sample Input

3 21 1 1-2 20 0-4 20 01 2 1 0 0 102 3 0 3 0 10

Sample Output

53样例解释:城市1买入5个单位电力, 花费5.城市1输出6个单位电力到城市2, 花费36.城市3输出4个单位电力到城市3, 花费12.总花费53. 

Data Constraint

对于5%的数据满足m = 0.
对于30%的数据满足n <= 30, L = 0, a = 0.
对于60%的数据满足n <= 50, m <= 200.
对于100%的数据满足n <= 200, m <= 600, u != v, 1 <= u, v <= n, 1 <= a, b <=3, 1 <= L <= 10, 1 <= L <= U <= 100, 0 <= in, out <= 100, -5 <= left <= 5.

分析

题面已经很明显地告诉这是个网络流了,而且显然是上下界费用流

我们从s往所有为正数的点连一条费用0上下界都为ai的边,从所有为负数的点向t连一条费用0上下界为-ai的边

表示这个点一开始有这么多的电或需要输出这么多的电

然后每个点向t连无限流量,费用为输出的边,从s向每个点连无限流量,费用为输入的边

然后对于电线的消耗,这是个二次函数,所以要拆开写

权值就会变为a+b,3*a+b,5*a+b,7*a+b……

先把下界的代价加进去,然后为了防止TLE,我们采用动态加边的方法

上下界网络流戳这个大爷

#include <iostream>
#include <cstdio>
#include <queue>
#include <memory.h>
using namespace std;
const int N=2e2+10;
const int M=6e2+10;
const int Inf=2147483647;
struct Edge {
    int u,v,l,r,a,b;
}e[M];
struct Graph {
    int v,c,w,nx;
}g[10000010];
int cnt=1,list[N],dis[N],vis[N],a[N],I[N][N],f[N];
int s,t,ss,tt;
int n,m,ans;

void Add_Edge(int u,int v,int c,int w) {
    g[++cnt]=(Graph){v,c,w,list[u]};list[u]=cnt;
    g[++cnt]=(Graph){u,0,-w,list[v]};list[v]=cnt;
}

void Add_Pipe(int u,int v,int l,int r,int w) {
    Add_Edge(u,v,r-l,w);
    if (l) a[u]-=l,a[v]+=l,ans+=w*l;
}

bool SPFA() {
    queue<int> q;
    while (!q.empty()) q.pop();
    memset(dis,0x7f,sizeof dis);memset(vis,0,sizeof vis);
    q.push(ss);vis[ss]=1;dis[ss]=0;
    for (int i=1;i<=m;i++)
        if (I[e[i].u][e[i].v]==e[i].l&&e[i].l<e[i].r) {
            e[i].l++;
            Add_Edge(e[i].u,e[i].v,1,(2*e[i].l-1)*e[i].a+e[i].b);
        }
    while (!q.empty()) {
        int u=q.front();q.pop();
        for (int i=list[u];i;i=g[i].nx)
            if (g[i].c&&dis[g[i].v]>dis[u]+g[i].w) {
                dis[g[i].v]=dis[u]+g[i].w;f[g[i].v]=i;
                if (!vis[g[i].v]) q.push(g[i].v);
                vis[g[i].v]=1;
            }
        vis[u]=0;
    }
    return dis[tt]!=0x7f7f7f7f;
}

void MCF() {
    int x=tt;
    while (f[x]) {
        ans+=g[f[x]].w;
        I[g[f[x]^1].v][g[f[x]].v]++;I[g[f[x]].v][g[f[x]^1].v]--;
        g[f[x]].c--;g[f[x]^1].c++;
        x=g[f[x]^1].v;
    }
}

void Dinic() {
    while (SPFA())
        MCF();
}

int main() {
    scanf("%d%d",&n,&m);
    s=0;t=n+1;ss=n+2;tt=n+3;
    Add_Pipe(t,s,0,Inf,0);
    for (int i=1;i<=n;i++) {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        if (a>0) Add_Pipe(s,i,a,a,0); else Add_Pipe(i,t,-a,-a,0);
        Add_Pipe(s,i,0,Inf,b);Add_Pipe(i,t,0,Inf,c);
    }
    for (int i=1;i<=m;i++) {
        scanf("%d%d%d%d%d%d",&e[i].u,&e[i].v,&e[i].a,&e[i].b,&e[i].l,&e[i].r);
        Add_Pipe(e[i].u,e[i].v,e[i].l,e[i].l,0);
        ans+=e[i].a*e[i].l*e[i].l+e[i].b*e[i].l;
        I[e[i].u][e[i].v]+=e[i].l;I[e[i].v][e[i].u]-=e[i].l;
    }
    for (int i=s;i<=t;i++) if (a[i]<0) Add_Pipe(i,tt,0,-a[i],0); else Add_Pipe(ss,i,0,a[i],0);
    Dinic();
    printf("%d",ans);
}

原文地址:https://www.cnblogs.com/mastervan/p/11145008.html

时间: 2024-12-13 13:29:32

[上下界费用流]JZOJ 3302 供电网络的相关文章

hdu 4862 Jump 上下界费用流

对于每个点拆点成为两个点a,b,连接a到b的上界为1,下界为1的边,保证用过一次且仅一次. 然后若点u可到达点v,则连接即可.建成了一个上下界网络,将下界拆出去,求最大费用最大流就好. #include <stdio.h> #include <iostream> #include <string.h> using namespace std; const int N=800; const int MAXE=200000; const int inf=1<<3

【bzoj1927】[Sdoi2010]星际竞速 有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6832464.html 题目描述 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的梦想,来自杰森座α星的悠悠也是其中之一.赛车大赛的赛场由N颗行星和M条双向星际航路构成,其中每颗行星都有一个不同的引力值.大赛要求车手们从一颗与这N颗行星之间没有任何航路的天体出发,访问这N颗行星每颗恰好一次,首先完成这一目标的人获得胜利.由于赛制非常开放,很多人驾驶着千奇百怪的自制赛

【bzoj4108】[Wf2015]Catering 有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6832537.html 题目描述 有一家装备出租公司收到了按照时间顺序排列的n个请求. 这家公司有k个搬运工.每个搬运工可以搬着一套装备按时间顺序去满足一些请求.一个搬运工从第i个请求的位置把东西搬到第j个请求的位置需要一些费用.公司的编号是1,请求的编号是2到n+1.所有搬运工必需从公司出发. 求满足所有请求所需的最小搬运费用. 输入 有可能有多组数据.(实际上没有) 第一行两个正整数n,k. 接下来n行,第i行

【bzoj2324】[ZJOI2011]营救皮卡丘 最短路-Floyd+有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend/p/6832504.html 题目描述 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双向道路.据点分别从1到N标号.小智一行K人从真新镇出发,营救被困在N号据点的皮卡丘.为了方便起见,我们将真新镇视为0号据点,一开始K个人都在0号点. 由于火箭队的重重布防,要想摧毁K号据点,必须

Acdream 1171 Matrix sum 上下界费用流

题目链接:点击打开链接 Matrix sum Time Limit: 8000/4000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description sweet和zero在玩矩阵游戏,sweet画了一个N * M的矩阵,矩阵的每个格子有一个整数.zero给出N个数Ki,和M个数Kj,zero要求sweet选出一些数,满足从第 i 行至少选出了Ki

zoj 3231(上下界费用流)

题意:树上每个节点上有若干苹果,边上带权,问你最小费用使得书上的苹果方差最小. 思路:上下费用流问题,参考http://blog.csdn.net/qq564690377/article/details/8870587 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last m

【bzoj2055】80人环游世界 有上下界费用流

原文地址:http://www.cnblogs.com/GXZlegend 题目描述 想必大家都看过成龙大哥的<80天环游世界>,里面的紧张刺激的打斗场面一定给你留下了深刻的印象.现在就有这么 一个80人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. 因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第i个人的游历路线为P1.P2......Pk(0≤k≤N),则P1<P2<......<Pk. 众所周知,中

P4043 [AHOI2014/JSOI2014]支线剧情 上下界费用流

题意: 有个人每次可以从1出发(可以无限次)  走有向边  耗费的时间为有向边的长度   问最少耗费的时间遍历所有的边至少一次 有点像滑雪那题  不过那题求得是最少的次数 这题很显然可以转化为上下界费用流  只要设置边的容量为1-inf 即可 注意: 上下界费用流的答案为: 答案即为(求出的费用+原图中边的下界*边的费用) 答案即为(求出的费用+原图中边的下界*边的费用) 答案即为(求出的费用+原图中边的下界*边的费用) 答案即为(求出的费用+原图中边的下界*边的费用) #include<bit

[AHOI2014][bzoj3876] 支线剧情 [上下界费用流]

题面 传送门 思路 转化模型:给一张有向无环图,每次你可以选择一条路径走,花费的时间为路径上边权的总和,问要使所有边都被走至少一遍(可以重复),至少需要花费多久 走至少一遍,等价于覆盖这条边 也就是说,我们要找这个图的一个可重复的路径覆盖 路径覆盖让我们想到什么算法了呢? 网络流啊! 我们考虑建立网络流图模型. 这道题里面有个关键:走过一条边,走几次就要花几次的费用,这想到什么? 费用流嘛! 我们定义走一次路径会给这条路径上的所有边增加1的流量,再给所有边赋一个费用等于边权 这样,我们只要设每条