【HDU2018多校赛第十场】Videos

最后一场比赛也结束了……

+HDU传送门+


◇ 题目

<简要翻译>

有n个人以及m部电影,每个人都有一个快乐值。每场电影都有它的开始、结束时间和看了这部电影会得到的快乐值。电影分成两种类型,若同一个人连续(不是时间连续,是顺序连续)看了两部相同类型的电影,他的快乐值会扣除W,数据保证扣除的值不超过电影增加的快乐值。

特别的,一个人换电影不花费时间,即若第一部电影的结束时间等于下一部电影的开始时间,是可以两场都看的;看电影必须看完;一部电影只能一个人看。

<输入&输出>

输入包含多组数据,第一行为整数T表示数据组数。

每组数据第一行包含四个整数t,m,n,W,t表示电影结束的最晚时间不超过t,m表示电影的数量,n表示人的数量,W表示连续看相同类型的电影扣除的快乐值;接下来m行,每行描述一个电影,包含四个整数——s[i]、e[i]表示第i部电影的开始和结束时间,w[i]表示看第i部电影得到的快乐值,k[i]表示电影的类型,为0或1。

输出所有人的快乐值之和的最大值。

<样例&解释>

Input Output Explain

2
10 3 1 10
1 5 1000 0
5 10 1000 1
3 9 10 0
10 3 1 10
1 5 1000 0
5 10 1000 0
3 9 10 0

2000

1990

第一组数据只有一个人,依次看了

第1,2部电影;

第二组数据只有一个人,依次看了

第1,2部电影,但类型相同,扣除

10;


◇ 解析

这道题是一道网络流的题……其中网络流的部分是队友不知道哪里找来的版,就不解释了QwQ

由于网络流的最大流无法处理多个人的情况,我们使用费用流,那么思路就非常清晰了——网络流中“流”的是人的个数,而费用就是每部电影的快乐值;

也就是说我们要求一个最大费用费用流,其实可以将所有边的费用取相反数,然后跑最小费用就可以了?

唯一难的就是建图。下面就直接列出建图方法了:

① 总共有n个人,为了避免一个人同时看了两部电影,我们先建立n个点每个点表示一个人,连接超级源点,容量为1(一个人),费用为0;

② 总共m部电影,一个人可以从任何一个电影开始看,所以建立m个节点,将每一部电影都跟所有的人连接,容量为1,费用为电影的快乐值(走过这条边就会增加快乐值,相当于看了这部电影,且限制了看电影的人数);

③ 若第i部电影的结束时间小于等于第j部电影的结束时间,则在第i部电影和第j部电影之间连边,容量依然为1,费用为第j部电影的快乐值,若电影i,j的类型相同,边的费用减去W(看完第i部电影再看第j部);

④ 由于一个人可以看完一部电影就不看了,即可以从任何一部电影结束,所以将所有电影与超级汇点连边;没有必要在人与汇点连边,因为看一部电影始终优于不看,则限制每个人都要看电影。

但是交上去就WA了,后面一个dalao来检查了一下~发现了一个BUG:

虽然有边的容量限制人数,但是下面这种情况会出现两个人看了同一部电影:

如何解决这种问题?

根据以前做题的经验(好吧,其实是dalao直接告诉我们的)我们需要拆点——将每一个电影节点拆分出一个虚拟节点,真节点与虚拟节点之间连一条容量为1,花费为0的边,所有以电影i为末尾的边都连在真节点上,而以电影i出发的边都连在虚拟节点上——只要经过电影i,则必然要通过真节点和虚拟节点的边,这样就限制了一个人通过。

虽然话是这么说,但是实际上建边时,边的花费我都取了相反数,这样就能够用跑最小费用流代替最大费用流,有负权边,注意选择合适的方法。


◇ 源代码(其中最小费用流的部分是从不知道哪个dalao那里copy过来的……真是非常感谢!!)

/*Lucky_Glass*/
#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
/*以下均是模板*/
const int N = 50002;
const int M = 500005;
#define INF 0x3f3f3f3f
struct E
{int to,cap,cost,flow,next;
}e[2*M];int head[N] , ecnt;
int  pre[N];
int dis[N];
bool vis[N];
int n,m,S,T;void Clear()
{ecnt = 0;memset(head,-1,sizeof head);
}void adde(int fr,int to,int cap,int cost)
{e[ecnt]=(E){to,cap,-cost,0,head[fr]};head[fr] = ecnt++;e[ecnt]=(E){fr,0,cost,0,head[to]};head[to] = ecnt++;
}bool SPFA(int s,int t)
{memset(vis,0,sizeof vis);memset(dis,0x3f,sizeof dis);memset(pre,-1,sizeof pre);queue <int> q;q.push(s);dis[s] = 0;vis[s]=1;while (!q.empty()){int cur = q.front();q.pop();vis[cur] = false;for (int j=head[cur];j!=-1;j=e[j].next){int to = e[j].to;if (dis[to] > dis[cur] + e[j].cost && e[j].cap > e[j].flow ){dis[to] = dis[cur] + e[j].cost;pre[to] = j;if (!vis[to]){q.push(to);vis[to] = true;}}}}return pre[t] != -1;
}void MCMF (int s,int t,int &maxflow,int &mincost)
{maxflow = mincost = 0;while (SPFA(s,t)){int MIN = INF;for (int j=pre[t]; j!=-1;j=pre[e[j^1].to]){MIN = min(MIN,e[j].cap - e[j].flow);}for (int j=pre[t]; j!=-1;j=pre[e[j^1].to]){e[j].flow += MIN;e[j^1].flow -= MIN;mincost += MIN * e[j].cost;}maxflow += MIN;}
}
/*模板结束*/
#define MAXN 3000int L[MAXN+5],R[MAXN+5],Lk[MAXN+5],Kd[MAXN+5];
int main(){int TT;cin>>TT;//数据组数 while(TT--){Clear();//清空 int nn,mm,kk,ht;cin>>nn>>mm>>kk>>ht;for(int i=1;i<=mm;i++)cin>>L[i]>>R[i]>>Lk[i]>>Kd[i];S=1,T=kk+mm*2+2;
//超级源点为1,超级汇点为最后一个点(因为有kk个人节点,mm*2个电影节点,即真节点和虚拟节点,再加上一个源点) for(int i=1;i<=kk;i++)adde(S,i+1,1,0); //在人节点和源点之间连边,第i个人编号为i+1 for(int i=1;i<=kk;i++)for(int j=1;j<=mm;j++)adde(i+1,j+kk+1,1,Lk[j]); //在人和电影的真节点之间连边,第i部电影真节点编号为i+kk+1 for(int i=1;i<=mm;i++)adde(i+kk+1,i+kk+mm+1,1,0); //连接真节点和虚拟节点,第i部电影的虚拟节点编号为i+kk+mm+1 for(int i=1;i<=mm;i++)adde(i+kk+mm+1,T,1,0); //连接虚拟节点和汇点 for(int i=1;i<=mm;i++)for(int j=1;j<=mm;j++)if(i!=j&&R[i]<=L[j]){ //电影之间连边,虚拟节点连真节点 if(Kd[i]!=Kd[j])adde(i+kk+mm+1,j+kk+1,1,Lk[j]);elseadde(i+kk+mm+1,j+kk+1,1,Lk[j]-ht);}int ans1,ans2;MCMF(S,T,ans1,ans2);cout<<-ans2<<"\n"; //由于边权取了相反数,输出答案时也需要取相反数 }
}

  


The End

Thanks for reading!

- Lucky_Glass

(Tab:如果我有没讲清楚的地方可以直接在邮箱lucky_glass@foxmail.com email我,在周末我会尽量解答并完善博客~?)

转载于:https://www.cnblogs.com/LuckyGlass-blog/p/9519886.html

【杂题总汇】HDU多校赛第十场 Videos相关推荐

  1. hdu 多校赛 第三场

    slove  2/11 rank  288 补题   5/11 --------------------------------------------------- 6604 Blow up the ...

  2. 2022杭电多校赛第八场

    2022杭电多校赛第八场 文章目录 2022杭电多校赛第八场 1004.Quel'Thalas 1001.Theramore 1011.Stormwind 1008.Orgrimmar 1005.Ir ...

  3. 2019牛客多校训练第十场F Popping Balloons

    2019牛客多校训练第十场F Popping Balloons 题意:二维平面内给你若干个点,然后你可以在x轴和y轴分别射三枪(每一枪的间隔是R),问最多能射掉多少气球. 题解:贪心.这个应该只能算作 ...

  4. 【杂题总汇】HDU-6406 Taotao Picks Apples

    [HDU 6406]Taotao Picks Apples 多校赛的时候多写了一行代码就WA了--找了正解对拍,在比赛结束后17分钟AC了? ◇ 题目 +传送门+ <手写翻译> 有n个苹果 ...

  5. hdu 多校赛 第二场

    slove  3/12 rank  224 补题   6/12 --------------------------------------------------- hdu 6595 http:// ...

  6. 【杂题总汇】NOIP2013(洛谷P1967) 货车运输

    [洛谷P1967] 货车运输 重做NOIP提高组ing... +传送门-洛谷P1967+ ◇ 题目(copy from 洛谷) 题目描述 A国有n座城市,编号从1到n,城市之间有m条双向道路.每一条道 ...

  7. 2015 多校赛 第三场 1002 (hdu 5317)

    Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and more i ...

  8. 2019牛客网暑期多校赛第七场C题Governing sand --思维+前缀和

    链接:https://ac.nowcoder.com/acm/contest/887/C 来源:牛客网 时间限制:C/C++ 3秒,其他语言6秒 空间限制:C/C++ 65536K,其他语言13107 ...

  9. 题解 | Coffee Chicken-2019牛客暑期多校训练营第十场B题

    题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss 题目描述: 输入描述: 输出描述: 示例1: 题解: 代码: #!/usr/bin/pyth ...

  10. 题解 | Popping Balloons-2019牛客暑期多校训练营第十场F题

    题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss 题目描述: 输入描述: 输出描述: 示例1: 示例2: 题解: 代码: #include&l ...

最新文章

  1. 18,rand('state',sum(100*clock))
  2. Tomcat中的线程池(APR和ThreadPool)
  3. Flask-分开Models解决循环引用
  4. jQuery-给ul添加了li之后,添加的li并没有绑定点击监听怎么办?
  5. conversation:in Good common
  6. 【职场】公子龙:在工作方向的选择上从设限到不设限
  7. BOOST_VMD_ASSERT_IS_LIST相关的测试程序
  8. 专科计算机网络期末考试,计算机网络(专科)期末练习题.doc
  9. python基础之拆包、匿名函数、文件的初级应用
  10. 二叉树关于,前序遍历的输入是否规范问题、
  11. ZOJ 1606 Count the Colors (线段数染色)
  12. meanShift算法用于目标跟踪的优缺点
  13. C Primer Plus 第6版第二章的作业
  14. Matlab------在Matlab中如何画圆
  15. JQuery选择器超级详细
  16. 本地数据下,radiobutton和图片组合,利用adapter+listview进行单选
  17. Java Web 后续(三)
  18. yii mysql gii_yii中gii如何使用
  19. MySQL知道出生日期如何计算年龄
  20. HTML基础之 HTML5新增视频和音频标签

热门文章

  1. [Python设计模式] 第14章 老板来了——观察者模式
  2. group by having where order by
  3. 查看Unix系统是32位还是64位
  4. 【Android】proguard混淆代码
  5. Swift 新建 APP 黑屏问题
  6. oracle用户口令已失效
  7. 算法复习周------“动态规划之‘图像压缩’”
  8. 读Zepto源码之Callbacks模块
  9. PHP伪造referer突破网盘禁止外链(附115源码)
  10. 使用apktool.jar工具反编译和回编译Android APK 终端命令模式