题面

​ 又一次考试网络流爆零......

​ 这一题一看就是网络流, 但是要怎么构图呢? 考虑到途中的一些因素, 首先, 每一种志愿者控制的区间范围为\(S_{i}\)到\(T_{i}\), 所以, 我们要使得每种志愿者只能控制这段区间, 其他的不能够控制, 其次, 每个时间都有一个最小的值, 也就是这条边(我们将时间段看为一条边更加方便)有一个下界, 想到了什么, 上下界网络流, 每条边都要符合上界和下界的约束, 没有学过的可以戳一下.

​ 那么初始的构图也就出来了, 每个时间作为一条边, 那么由\(i\)向\(i + 1\)连一条边, 容量为\(INF - lower(i)\), 费用为0(由于人是控制一段区间的, 他在这段区间中的任意两个点流费用都为0, 可以看做这个人继续做事, 已经付钱了, 你得给我做完事才能走)(\(lower(i)\)代表时间\(i\)最少需要多少人, 其实这条边容量为\(INF\)没有问题, 假装上界为\(INF + lower(i)\)就可以了, 反正可以不停地流), 考虑到之前所说, 每个点只能约束自己的一段区间, 有点像循环流, 从\(S_{i}\)出发, 流到\(T_{i}\)就重新流, 但是这里由于\(T_{i}\)被看成了一条边, 所以我们需要在点\(T_{i} + 1\)往\(S_{i}\)连一条容量为\(INF\), 费用为\(c\)的边, 代表当前类\(i\)的志愿者控制且只能控制\(S_{i}\)到\(T_{i}\)这段时间.

​ 最终构图是这样的: 每个点\(i\)向\(i + 1\)连边, 每个\(T_{i} + 1\)向\(S_{i}\)连边, 注意在每个点\(i\)向\(i + 1\)连边时, 由于你是默认这条边流了一个下界的, 你每个点的流量不一定平衡, 记录一下每个点流入和流出的差, 对于一条下界为\(x\)的边i -> i + 1, 记\(delta[i]\)为点\(i\)流入与流出的差, 则\(delta[i] -= x\), \(delta[i + 1] += x\), 连完所有边后, 注意到每个点的\(delta\)不一定为0, 对于\(delta\)大于或者小于0的情况, 戳上面那个吧, 有详细的介绍, 最后跑一遍无源汇上下界最小费用可行流就可以了, 也就是在构出的有源汇的图中跑一遍最小费用最大流即可.

具体代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define N 2005
#define INF 1e9
using namespace std; int n, m, S, T, delta[N], head[N], cnt = 1, p[N], vis[N];
struct node
{
int from, to, next;
long long flow, cost;
} edge[100005];
long long a[N], d[N]; inline int read()
{
int x = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * w;
} inline void add(int u, int v, long long w, long long cost)
{
edge[++cnt] = { u, v, head[u], w, cost }; head[u] = cnt;
edge[++cnt] = { v, u, head[v], 0, -cost }; head[v] = cnt;
} bool SPFA(long long &cost)
{
memset(d, 0x3f, sizeof(d)); memset(a, 0x3f, sizeof(a));
queue<int> q; q.push(S); d[S] = 0; vis[S] = 1;
while(!q.empty())
{
int u = q.front(); q.pop(); vis[u] = 0;
for(int i = head[u]; i; i = edge[i].next)
{
int v = edge[i].to;
if(d[v] > d[u] + edge[i].cost && edge[i].flow > 0)
{
d[v] = d[u] + edge[i].cost; a[v] = min(a[u], edge[i].flow);
p[v] = i; if(!vis[v]) { vis[v] = 1; q.push(v); }
}
}
}
if(d[T] == d[0]) return 0;
cost += (a[T] * d[T]);
for(int i = T; i != S; i = edge[p[i]].from)
{
edge[p[i]].flow -= a[T]; edge[p[i] ^ 1].flow += a[T];
}
return 1;
} int main()
{
n = read(); m = read();
S = n + 2; T = S + 1;
for(int i = 1; i <= n; i++) { int x = read(); add(i, i + 1, INF, 0); delta[i] -= x; delta[i + 1] += x; }
for(int i = 1; i <= m; i++)
{
int u = read(), v = read(), c = read();
add(v + 1, u, INF, c);
}
for(int i = 1; i <= n + 1; i++)
{
if(delta[i] < 0) add(i, T, -delta[i], 0);
if(delta[i] > 0) add(S, i, delta[i], 0);
}
long long cost = 0;
while(SPFA(cost));
printf("%lld\n", cost);
return 0;
}

[luogu3980] 志愿者招募的更多相关文章

  1. BZOJ 1061: [Noi2008]志愿者招募

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 4064  Solved: 2476[Submit][Stat ...

  2. BZOJ 1061: [Noi2008]志愿者招募 [单纯形法]【学习笔记】

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3975  Solved: 2421[Submit][Stat ...

  3. BZOJ-1061 志愿者招募 线性规划转最小费用最大流+数学模型 建模

    本来一眼建模,以为傻逼题,然后发现自己傻逼...根本没想到神奇的数学模型..... 1061: [Noi2008]志愿者招募 Time Limit: 20 Sec Memory Limit: 162 ...

  4. [BZOJ1061][Noi2008]志愿者招募

    [BZOJ1061][Noi2008]志愿者招募 试题描述 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难 题:为即将启动的奥运新项目招募一批短期志愿 ...

  5. bzoj 1061 志愿者招募(最小费用最大流)

    [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3792  Solved: 2314[Submit][Status][Di ...

  6. 【BZOJ】【1061】【NOI2008】志愿者招募

    网络流/费用流 OrzOrzOrz,这题太神了不会捉. 题解:https://www.byvoid.com/blog/noi-2008-employee/ 这道题正确的解法是构造网络,求网络最小费用最 ...

  7. BZOJ 1061: [Noi2008]志愿者招募 费用流

    1061: [Noi2008]志愿者招募 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1061 Description 申奥成功后,布布 ...

  8. bzoj1061: [Noi2008]志愿者招募

    线性规划与费用流.http://www.cnblogs.com/iiyiyi/p/5616080.html.数组范围开错了!!!然后2.31-1=0x7fffffff!=0x7f7f7f7f. 开始以 ...

  9. NOI2008 志愿者招募

    1061: [Noi2008]志愿者招募 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1859  Solved: 1169[Submit][Stat ...

随机推荐

  1. SpringBoot,Vue前后端分离开发首秀

    需求:读取数据库的数据展现到前端页面 技术栈:后端有主要有SpringBoot,lombok,SpringData JPA,Swagger,跨域,前端有Vue和axios 不了解这些技术的可以去入门一 ...

  2. HDU3534(SummerTrainingDay13-C tree dp)

    Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. JS 的map和array集合组合返回JSON字符串

    使用map 和array 返回自定义对象的JSON字符串: function getObjectJSON() { var array = new Array(); for (var i = 0; i ...

  4. js-ES6学习笔记-Class(4)

    1.Object.getPrototypeOf方法可以用来从子类上获取父类.因此,可以使用这个方法判断,一个类是否继承了另一个类. 2.super这个关键字,既可以当作函数使用,也可以当作对象使用.在 ...

  5. Ajax常见面试题 -- 前端面试题(二)

    1:什么是ajax?ajax作用是什么? 异步的javascript和xml AJAX 是一种用于创建快速动态网页的技术. ajax用来与后台交互   2:原生js ajax请求有几个步骤?分别是什么 ...

  6. 【读书笔记】iOS-网络-解析响应负载

    Web Service可以通过多种格式返回结构化数据, 不过大多数时候使用的是XML与JSON.也可以让应用只接收HTML结构的数据.实现了这些Web Service或是接收HTML文档的应用必须能解 ...

  7. SpringCloud 组件Eureka参数配置项详解

    Eureka涉及到的参数配置项数量众多,它的很多功能都是通过参数配置来实现的,了解这些参数的含义有助于我们更好的应用Eureka的各种功能,下面对Eureka的配置项做具体介绍,供大家参考. Eure ...

  8. 反射和动态加载bean 完成 通用servie

    最近我们部门有个小项目,用来管理这个公司所有项目用到的代码表,例如国家代码.行政区划代码等.这个项目的功能其实很少,就是简单的修改.查询.新增和逻辑删除.但是为每张表都写一套增删改查的页面和一套ser ...

  9. Asp Url汉字乱码的问题

    1.js <a target="_blank" href="/asp/download.asp?File=' + escape(item.FileName) + ' ...

  10. Android--将实体类转化成Json和Map的基类

    package com.newair.talk.base; import android.text.TextUtils; import com.google.gson.Gson; import jav ...