题意: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. CI 点击图片刷新验证码

    <img src="<?php echo site_url('home/login/code'); ?>" onclick= this.src="< ...

  2. css背景图片拉伸

    css背景图片拉伸 background-image:url(bg.png); -moz-background-size: 100% 100%; -o-background-size: 100% 10 ...

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

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

  4. 几种排序算法的java实现

    import java.util.Arrays; /** * 各种排序算法从小到大进行排序 */ public class Test { public static void main(String ...

  5. jQuery多项选项卡的实现

    请勿盗版.转载请加上出处http://blog.csdn.net/yanlintao1 请勿盗版,转载请加上出处http://blog.csdn.net/yanlintao1 css样式: @CHAR ...

  6. MongoDB中关于查询条件中包括集合中字段的查询

    要查询的数据结构例如以下: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2FvMzY5NTE=/font/5a6L5L2T/fontsize/400/f ...

  7. redis php 实例一

    下面的例子都是基于php-redis这个扩展的. 1,connect 描述:实例连接到一个Redis. 参数:host: string,port: int 返回值:BOOL 成功返回:TRUE;失败返 ...

  8. php 对字符串的分块处理

    //如何把以下的字符串分成每一个小块, 如:2017.2.14\n我们都是中国人\n小日本 这样的为一个小块 $str = '2017.2.14 我们都是中国人 小日本 2017.2.15 订单取消 ...

  9. Maven使用deploy上传jar包到远程库 以Oracle驱动为例

    一.首先要得到Oracle JDBC Driver 1.通过Oracle官方网站下载相应版本:http://www.oracle.com/technetwork/database/features/j ...

  10. C++ 分割字符串两种方法

    原文地址:http://blog.csdn.net/xjw532881071/article/details/49154911 字符串切割的使用频率还是挺高的,string本身没有提供切割的方法,但可 ...