<题目链接>

题目大意:

一天有N个小时,有m个节目(每种节目都有类型),有k个人,连续看相同类型的节目会扣w快乐值。每一种节目有都一个播放区间[l,r]。每个人同一时间只能看一个节目,看完可以获得快乐值,每个节目只能被人看一次。问最多可以获得多少快乐?

解题分析:

本题用费用流求解的方式还是比较直观的。因为本题要求的是最大费用,所以我们需要建图的时候需要将所有实际费用取反,然后将最后最小费用最大流求出的答案取反,就是要求的最大费用。具体建图过程见代码:

#include <bits/stdc++.h>
using namespace std; #define clr(a,b) memset(a,b,sizeof(a))
template<typename T>
inline void read(T&x){
x=;int f=;char c=getchar();
while(c<'' || c>''){ if(c=='-')f=-;c=getchar(); }
while(c>='' && c<=''){ x=x*+c-'';c=getchar(); }
x*=f;
} //最小费用最大流模板
struct MCMF{
static const int N = 5e4+, M = 5e5+, INF = 0x7fffffff; int n, m, head[N], s, t, cnt;
int dist[N], inq[N], pre[N], incf[N];
int mxflow, mncost;
struct Edge{ int to, cap, cost, next; } edge[M * ]; inline void init(int l, int r, int ss, int tt){
//for(int i = l; i <= r; i++ ){head[i] = -1;}
memset(head, -, sizeof(head));
s = ss, t = tt, cnt = ;
mxflow = mncost = ;
}
inline void add(int u,int v,int cap,int cost){
edge[++cnt]=(Edge){v,cap,cost,head[u]};head[u]=cnt;
edge[++cnt]=(Edge){u,,-cost,head[v]};head[v]=cnt;
} bool spfa(int s, int t){ //slf优化的spfa(双端队列优化)
for(int i = ; i < N; i++)
dist[i] = INF, inq[i] = ;
clr(pre,);
deque<int>q;
inq[s]=,dist[s] = ;
q.push_back(s);
incf[s] = INF;
while(!q.empty()){
int u = q.front();q.pop_front();
inq[u] = ;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to,cap=edge[i].cap,cost=edge[i].cost;
if(cap> && dist[v]>dist[u]+cost){ //更新每个点的最小费用
dist[v]=dist[u]+cost;
incf[v]=min(incf[u], cap); //得到v点所在路径上的最小容量
pre[v]=i; //记录下这个点的前驱正向边
if(!inq[v]){
inq[v]=;
if(q.empty() || dist[v]>dist[q.front()])q.push_back(v);
else q.push_front(v); //如果最小费用小于等于队首,直接塞入队列首
}
}
}
}
return dist[t]!=INF;
}
void update(int s,int t){
int x=t;
while(x!=s){
int pos=pre[x];
edge[pos].cap-=incf[t];
edge[pos^].cap+=incf[t];
x=edge[pos^].to;
}
mxflow+=incf[t];
mncost+=dist[t]*incf[t];
}
void minCostMaxFlow(int s,int t){
while(spfa(s,t))
update(s,t);
}
}mcmf; const int NN = + ;
struct Node{ int l, r, w, fp; } node[NN]; int st,ed;
inline void GetMap(){
int n,m,k,w;
read(n);read(m);read(k);read(w);
st=,ed=*m+; //0代表源点,2*m+1代表慈元典,ed代表汇点
mcmf.init(st,ed,st,ed);
mcmf.add(st,*m+,k,); //源点向次源点连一条容量为k,费用为0的边
for(int i=;i<=m;i++)
scanf("%d%d%d%d",&node[i].l,&node[i].r,&node[i].w,&node[i].fp);
for(int i=;i<=m;i++){
for(int j=;j<=m;j++){
if(i==j)continue;
if(node[i].r<=node[j].l) //对于那些满足条件的video, i的出点向j的入点连一条容量为1,费用为0(或者如果这两个点类型相同的话,费用就为W,因为本题是将所有费用置为它的相反数了)
mcmf.add(i+m,j,,(node[i].fp==node[j].fp)?w:); //因为本题是求最大费用,所以要将所有费用取反,这里就是 w
}
}
for(int i=;i<=m;i++)
mcmf.add(i,i+m,,-node[i].w); //拆点,所有点的入点向入点连一条容量为1,费用为node[i].w的边
for(int i=;i<=m;i++)
mcmf.add(*m+,i,,); //源点向所有的点连上一条容量为1,费用为0的边
for(int i=;i<=m;i++)
mcmf.add(i+m,ed,,); //所有点的出度连一条容量为1,费用为0的边
}
inline void Solve(){
mcmf.minCostMaxFlow(st,ed);
printf("%d\n",-mcmf.mncost); //取相反数,就是实际意义上的最大费用
}
int main(){
int T;cin>>T;
while(T--){
GetMap();
Solve();
}
}

HDU 6437 Problem L.Videos (最大费用)【费用流】的更多相关文章

  1. HDU - 6437 Problem L.Videos 2018 Multi-University Training Contest 10 (最小费用最大流)

    题意:M个影片,其属性有开始时间S,结束时间T,类型op和权值val.有K个人,每个人可以看若干个时间不相交的影片,其获得的收益是这个影片的权值val,但如果观看的影片相邻为相同的属性,那么收益要减少 ...

  2. hdu6437 Problem L.Videos(网络流)

    Problem L.Videos Problem Description: C-bacteria takes charge of two kinds of videos: ’The Collectio ...

  3. HDU 6343.Problem L. Graph Theory Homework-数学 (2018 Multi-University Training Contest 4 1012)

    6343.Problem L. Graph Theory Homework 官方题解: 一篇写的很好的博客: HDU 6343 - Problem L. Graph Theory Homework - ...

  4. [hdu6437]Problem L. Videos

    题目大意:有$n$个小时,有$m$个节目(每种节目都有类型$0/1$),有$k$个人,一个人连续看相同类型的节目会扣$w$快乐值. 每一种节目有都一个播放区间$[l,r]$.每个人同一时间只能看一个节 ...

  5. HDU 6330.Problem L. Visual Cube-模拟到上天-输出立方体 (2018 Multi-University Training Contest 3 1012)

    6330.Problem L. Visual Cube 这个题就是输出立方体.当时写完怎么都不过,后来输出b<c的情况,发现这里写挫了,判断失误.加了点东西就过了,mdzz... 代码: //1 ...

  6. HDU 6343 - Problem L. Graph Theory Homework - [(伪装成图论题的)简单数学题]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6343 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  7. HDU 6437 最(大) 小费用最大流

    Problem L.Videos Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Other ...

  8. HDU 5988.Coding Contest 最小费用最大流

    Coding Contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  9. hdu 3395(KM算法||最小费用最大流(第二种超级巧妙))

    Special Fish Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

随机推荐

  1. 010 socket定义服务器

    using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Ne ...

  2. 快速掌握Nginx(四) —— Nginx日志切片和常用配置总结

    1.Nginx日志管理 1.日志简单介绍 Nginx提供了日志记录的功能,日志文件在对我们管理网站十分有用,通过访问日志(access_log)我们可以获取请求来源.客户端信息.请求的资源等信息:通过 ...

  3. 实现Map接口(hash原理)

    闲来无事,就实现一个简单的map来练练手吧! HashMap的底层实现主要是基于数组和链表来实现的,HashMap中通过key的hashCode来计算hash值的,由这个hash值计算在数组中的位置, ...

  4. Python高级笔记(二) -- 深拷贝和浅拷贝

    1. 深拷贝 1.1 类型1 注意: d没有改变, 因为d所拷贝的数据没有改变, 而是c往后添加数据. 1.2 类型2: 元组 如果copy.copy拷贝的是元组是深拷贝! 不会进行浅拷贝, 仅仅是指 ...

  5. 试用VS2019正式版

    1.下载地址https://visualstudio.microsoft.com/zh-hans/downloads/2.安装,安装过程比较简单,直接下一步,下一步即可,现在的网速一般下载+安装要2个 ...

  6. [Luogu P2966][BZOJ 1774][USACO09DEC]牛收费路径Cow Toll Paths

    原题全英文的,粘贴个翻译题面,经过一定的修改. 跟所有人一样,农夫约翰以宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生财之道.为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道 ...

  7. unix域数据报回射程序(不完整)

    一.服务器程序 int main(int argc, char **argv) { int sockfd; struct sockaddr_un servaddr, cliaddr; sockfd = ...

  8. 关于接口(Interface)

    接口,其实是指类之间约定的协议,可以包含方法.属性.事件和索引: 接口成员不允许使用访问修饰符号(public.private.protected.internal),所有的接口成员都是公共的. 接口 ...

  9. 移除文件(git rm)

    git rm`命令会把文件从已跟踪列表(及暂存区)中移除,并且移除把文件从工作目录中移除,这样下一次你就不会在未跟踪文件列表中看到这些文件了. 如果你只是简单的把文件从工作目录移除,而没有使用git ...

  10. [系统集成] 基于 elasticsearch 的企业监控方案

    注: 2017年10月16日: 使用中发现 es 查询时序数据的性能较差,且 watch 脚本的编写比较麻烦,因此已将监控系统切换到了 influxdb+grafana平台.新监控系统各方面情况比较满 ...