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

分析:因为人数不定,所以贪心和dp的思路被否定了。1对多的带权匹配,求最大权,这种问题显然KM是解决不了的,那么只能是最小费用最大流了。而这题要求的是最大收益,那么建负权边即可。

为了保证每个影片只被一个人观看,将其拆为入点和出点,入点和出点之间连一条容量为1,花费为0的边,网络流建图的基本操作。

首先虚拟一个源点st和源点big。从big向st建一条容量为K,花费为0的边,表示有K个人可以进行接下来选影片的操作。

从st点向每个入点连一条容量为1,花费为-val[i]的边,表示每个影片都可以作为某个人最先观看的影片。

若两个影片的时间不相交(u->T <= v->S),那么在u到v之间建一条容量为1,花费为-val[v]的边;若u,v属性相同则花费为-val[v]+W。

最后将每个出点向汇点连一条容量为1,花费为0的边。

跑出的最小花费取反就是所求答案。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge{
int to, next, cap, flow, cost;
} edge[MAXM];
int head[MAXN], tol;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N; //0~N-1的点数
void init(int n)
{
N = n;
tol = ;
memset(head, -, sizeof(head));
} void addedge(int u, int v, int cap, int cost)
{
edge[tol].to = v;
edge[tol].cap = cap;
edge[tol].cost = cost;
edge[tol].flow = ;
edge[tol].next = head[u];
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = ;
edge[tol].cost = -cost;
edge[tol].flow = ;
edge[tol].next = head[v];
head[v] = tol++;
} bool spfa(int s, int t){
queue<int> q;
for (int i = ; i < N; i++){
dis[i] = INF;
vis[i] = false;
pre[i] = -;
}
dis[s] = ;
vis[s] = true;
q.push(s);
while (!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for (int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].to; if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost){
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
if (pre[t] == -) return false;
else return true;
} int minCostMaxflow(int s, int t, int &cost){
int flow = ;
cost = ;
while (spfa(s, t)){
int Min = INF;
for (int i = pre[t]; i != -; i = pre[edge[i ^ ].to]){
if (Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
}
for (int i = pre[t]; i != -; i = pre[edge[i ^ ].to]){
edge[i].flow += Min;
edge[i ^ ].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
} int n,M,K,W; struct Node{
int s,t,op,val;
}pt[MAXN]; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int T; scanf("%d",&T);
while(T--){
scanf("%d %d %d %d",&n, &M, &K, &W);
int st = ,big =*M+;
int ed = big+;
init(*M+);
addedge(big,st,K,);
for(int i=;i<=M;++i){
scanf("%d%d%d%d",&pt[i].s,&pt[i].t, &pt[i].val, &pt[i].op);
addedge(st,i,,-pt[i].val);
addedge(i+M,ed,,);
addedge(i,i+M,,);
}
for(int i=;i<=M;++i){
for(int j=;j<=M;++j){
if(i==j) continue;
if(pt[i].t<=pt[j].s){
if(pt[i].op^pt[j].op){
addedge(i+M,j,,-pt[j].val);
}
else{
addedge(i+M,j,,-(pt[j].val-W));
}
}
}
}
int res;
minCostMaxflow(big,ed,res);
printf("%d\n",-res);
}
return ;
}

HDU - 6437 Problem L.Videos 2018 Multi-University Training Contest 10 (最小费用最大流)的更多相关文章

  1. HDU 6437 Problem L.Videos (最大费用)【费用流】

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

  2. HDU–5988-Coding Contest(最小费用最大流变形)

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

  3. HIT 2739 - The Chinese Postman Problem - [带权有向图上的中国邮路问题][最小费用最大流]

    题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2739 Time limit : 1 sec Memory limit : 64 M A Chinese ...

  4. 2018 Nowcoder Multi-University Training Contest 10

    Practice Link J. Rikka with Nickname 题意: 给出\(n\)个字符串,要求依次合并两个串\(s, t\),满足将\(t\)合并到\(s\)中变成\(r\),使得\( ...

  5. 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 - ...

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

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

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

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

  8. 2018 Multi-University Training Contest 10 Solution

    A - Problem A.Alkane 留坑. B - Problem B. Beads 留坑. C - Problem C. Calculate 留坑. D - Problem D. Permut ...

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

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

随机推荐

  1. javascript获取html标记的的绝对定位值

    function getElementLeft(element) { var actualLeft = element.offsetLeft; var current = element.offset ...

  2. find命令结合cp bash mv 命令使用的4种方式

    工作经常需要用find结合其它命令一起使用,下面介绍4种结合方式. 例: 用find查找/data目录下,以.txt文件结尾的文件并复制到/tmp下 方法一 find与|xargs是黄金搭档,-t 参 ...

  3. 修改net基本三层 动软生产

    控制层(dal) 模型层-实体类(Model) 显示层-web

  4. JavaScript如何实现计时功能。

    JavaScript如何实现计时功能. 解答:<script> window.setTimeout( “window.location = ‘http://www.csdn.net ‘; ...

  5. Educational Codeforces Round 22 E. Army Creation 主席树 或 分块

    http://codeforces.com/contest/813/problem/E 题目大意: 给出长度为n的数组和k,  大小是1e5级别. 要求在线询问区间[l, r]权值,  权值定义为对于 ...

  6. 【Raspberry pi】set up an ftp server

    http://www.debian-administration.org/articles/228 As a means of distributing large collections of fi ...

  7. Servlet及相关类和接口

    上一篇介绍了在Web项目中web.xml文件的配置信息,本篇主要介绍里面非常重要的配置——Servlet配置,重点介绍与Servlet相关的几个接口和类,包括Servlet接口.ServletConf ...

  8. 《从零开始学Swift》学习笔记(Day 58)—— Swift编码规范之变量或常量声明规范

    原创文章,欢迎转载.转载请注明:关东升的博客 声明是在声明变量.常量.属性.方法或函数和自定义类型时候需要遵守的规范. 首先变量或常量时每行声明变量或常量的数量推荐一行一个,因为这样以利于写注释.示例 ...

  9. Docker的初体验

    这几天捣鼓了一下docker,是真的麻烦啊,网上资料比较杂乱,也很多英文,学起来挺多问题的 Docker下载 win10专业版:开启Hyper-V,下载并安装 docker-for-windows(但 ...

  10. python框架Scrapy中crawlSpider的使用

    一.创建Scrapy工程 #scrapy startproject 工程名 scrapy startproject demo3 二.进入工程目录,根据爬虫模板生成爬虫文件 #scrapy genspi ...