题目链接:https://www.nowcoder.com/acm/contest/206/A

题目描述
恬恬的生日临近了。宇扬给她准备了一个蛋糕。
正如往常一样,宇扬在蛋糕上插了n支蜡烛,并把蛋糕分为m个区域。因为某种原因,他必须把第i根蜡烛插在第ai个区域或第bi个区域。区域之间是不相交的。宇扬在一个区域内同时摆放x支蜡烛就要花费x2的时间。宇扬布置蛋糕所用的总时间是他在每个区域花的时间的和。
宇扬想快些见到恬恬,你能告诉他布置蛋糕最少需要多少时间吗?
输入描述:
第一行包含两个整数n,m(1 ≤ n ≤ 50, 2≤ m≤ 50)。
接下来n行,每行两个整数ai,bi(1 ≤ ai, bi ≤ m)。
输出描述:
一个整数表示答案。
示例1
输入
3 3
1 2
1 2
1 2
输出
5
示例2
输入
3 3
1 2
2 3
1 3
输出
3

题解:

一开始有考虑从源点 $s$ 出发,连 $n$ 条流量上限为 $1$ 的边到左侧 $n$ 个节点($n$ 根蜡烛),右侧 $m$ 个区域作为 $m$ 个节点,并向汇点 $t$ 连 $m$ 条边,

而从左侧到右侧的连边则根据题目所给的 $a[i],b[i]$ 进行,最后跑最小费用最大流,但是没能想到如何处理费用放弃了。

看了题解之后,感觉建图还是比较巧妙的,

考虑上面的思路,对于原本是右侧 $m$ 个区域作为节点,现在将这 $m$ 个节点中任意第 $j$ 个节点,都拆分成 $n$ 个节点,将其看成一组,称作第 $j$ 组,

对于原本的第 $i$ 根蜡烛,原来是有两条流量上限为 $1$ 的出弧,分别连向右侧的第 $a[i]$ 和第 $b[i]$ 个节点的,

现在拆点后,就变成了 $2 \times n$ 条出弧了,其中 $n$ 条出弧连向第 $a[i]$ 组,$n$ 条出弧连向第 $b[i]$ 组,流量上限不变,

同时,对于右侧每一组的 $n$ 个节点,第 $1$ 个节点的所有入弧费用都设为 $1^2 - 0^2 = 1$,第 $2$ 个节点的所有入弧费用都设为 $2^2 - 1^2 = 3$,依次类推;

这样一来,就像蛋糕上每个区域,我都分出了 $n$ 个空位,由于最小费用的限制,所以插蜡烛只会往费用最小的空位插,就可以保证答案的正确性。

AC代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=;
  4. const int INF=0x3f3f3f3f;
  5.  
  6. struct Edge{
  7. int u,v,cap,flow,cost;
  8. };
  9. struct MCMF
  10. {
  11. int s,t; //源点汇点
  12. vector<Edge> E;
  13. vector<int> G[maxn];
  14. void init(int l,int r)
  15. {
  16. E.clear();
  17. for(int i=l;i<=r;i++) G[i].clear();
  18. }
  19. void addedge(int from,int to,int cap,int cost)
  20. {
  21. E.push_back((Edge){from,to,cap,,cost});
  22. E.push_back((Edge){to,from,,,-cost});
  23. G[from].push_back(E.size()-);
  24. G[to].push_back(E.size()-);
  25. }
  26.  
  27. int d[maxn],vis[maxn];
  28. int aug[maxn],pre[maxn];
  29. bool spfa(int s,int t,int &flow,int &cost)
  30. {
  31. memset(d,INF,sizeof(d));
  32. memset(vis,,sizeof(vis));
  33. queue<int> q;
  34. q.push(s);
  35. d[s]=, vis[s]=, pre[s]=, aug[s]=INF;
  36. while(!q.empty())
  37. {
  38. int now=q.front(); q.pop();
  39. vis[now]=;
  40. for(int i=;i<G[now].size();i++)
  41. {
  42. Edge& e=E[G[now][i]]; int nxt=e.v;
  43. if(e.cap>e.flow && d[nxt]>d[now]+e.cost)
  44. {
  45. d[nxt]=d[now]+e.cost;
  46. pre[nxt]=G[now][i];
  47. aug[nxt]=min(aug[now],e.cap-e.flow);
  48. if(!vis[nxt])
  49. {
  50. q.push(nxt);
  51. vis[nxt]=;
  52. }
  53. }
  54. }
  55. }
  56. if(d[t]==INF) return ;
  57. flow+=aug[t];
  58. cost+=d[t]*aug[t];
  59. for(int i=t;i!=s;i=E[pre[i]].u)
  60. {
  61. E[pre[i]].flow+=aug[t];
  62. E[pre[i]^].flow-=aug[t];
  63. }
  64. return ;
  65. }
  66.  
  67. int mc,mf;
  68. void solve()
  69. {
  70. int flow=,cost=;
  71. while(spfa(s,t,flow,cost));
  72. mc=cost;
  73. mf=flow;
  74. }
  75. }mcmf;
  76.  
  77. int n,m;
  78. int a[],b[];
  79. int main()
  80. {
  81. cin>>n>>m;
  82. for(int i=;i<=n;i++) cin>>a[i]>>b[i];
  83.  
  84. mcmf.init(,n+n*m+);
  85. mcmf.s=;
  86. mcmf.t=n+n*m+;
  87. for(int i=;i<=n;i++)
  88. {
  89. mcmf.addedge(mcmf.s,i,,);
  90. for(int j=,u,v;j<=n;j++)
  91. {
  92. u=i,v=n+(a[i]-)*n+j;
  93. mcmf.addedge(u,v,,*j-);
  94. u=i,v=n+(b[i]-)*n+j;
  95. mcmf.addedge(u,v,,*j-);
  96. }
  97. }
  98. for(int i=;i<=m;i++)
  99. for(int j=;j<=n;j++)
  100. mcmf.addedge(n+(i-)*n+j,mcmf.t,,);
  101.  
  102. mcmf.solve();
  103. printf("%d\n",mcmf.mc);
  104. }

nowcoder 206A - Birthday - [最小费用最大流]的更多相关文章

  1. HDU5988/nowcoder 207G - Coding Contest - [最小费用最大流]

    题目链接:https://www.nowcoder.com/acm/contest/207/G 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 ...

  2. 2018牛客网暑期ACM多校训练营(第五场) E - room - [最小费用最大流模板题]

    题目链接:https://www.nowcoder.com/acm/contest/143/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...

  3. 牛客2018多校第五场E-room 最小费用最大流

    题意:有n个寝室,每个寝室4个人,现在在搞搬寝室的活动,告诉你每个寝室之前的人员名单,和之后的人员名单,问最少需要几个人要搬寝室. 思路: 转化为最小费用最大流解决的二分图问题,对每个去年的宿舍,向每 ...

  4. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  5. bzoj1927最小费用最大流

    其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→   =_=你TM逗我 刚要删突然感觉dinic的模 ...

  6. ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)

    将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...

  7. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

  8. P3381 【模板】最小费用最大流

    P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...

  9. 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 502[Submit][Status ...

随机推荐

  1. 新手如何学习 jQuery?

    可以看张晓菲的<锋利的jQuery>,重点是自己理解函数用法并自行实现一些常用的效果.如果需要快速查阅可以用这个api,每个函数都附有简单的示例:http://api.jquery.com ...

  2. 使用dstat命令的插件查看mysql的io状态

    使用dstat竟然还可以查看mysql的状态, man dstat之后发现的,原来在/usr/share/dstat目录下藏有很多python脚本作为插件帮助dstat搜集各类信息. 不过通常有可能会 ...

  3. Spark 底层网络模块

    文章正文 对于分布式系统来说,网络是最基本的一环,其设计的好坏直接影响到整个分布式系统的稳定性及可用性.为此,Spark专门独立出基础网络模块spark-network,为上层RPC.Shuffle数 ...

  4. [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现

    [Android实例教程] 教你如何拍照+相册选择图片+剪裁图片完整实现 今天做Android项目的时候要用到图片选择,要实现拍照获取图片和从相册获取图片,并且要求在获取完之后可以裁剪,试了很多方法之 ...

  5. [ci]jenkins server启动,通过jnlp的方式启动slave(容器模式)

    jenkins server启动,通过jnlp的方式启动slave. java -jar jenkins.jar 配置jnlp端口--全局安全 配置云 配置项目 执行成功

  6. [svc]rsync简单部署

    安装rsync服务端-backup服务器 yum install rsync -y useradd rsync -s /sbin/nologin -M chown -R rsync.rsync /da ...

  7. Selenium Web 自动化 - 项目实战(二)

    Selenium Web 自动化 - 项目实战(二) 2016-08-08 什么是数据驱动?简答的理解就是测试数据决定了测试结果,这就是所谓数据驱动.数据驱动包含了数据,他就是测试数据,在自动化领域里 ...

  8. 设置gem源,解决下载慢的问题

    问题解决的最好方法方法 使用google的DNS 8.8.8.8 / 8.8.4.4 另一种解决方式 修改rubygems的source源 $ gem source -r http://rubygem ...

  9. Tensorflow学习笔记——安装和运行

    参考的资料: 1.官网 2.tensorflow官方文档中文版 安装的是Python 2.7; CPU support (no GPU support),版本是1.1 pip install tens ...

  10. 大数据学习笔记02-HDFS-常用命令

    创建目录 hadoop fs -mkdir [-p] hdfs://master:9999/user/hadoop-twq/cmd 上传文件 hadoop fs -put [-f -d] [local ...