nowcoder 206A - Birthday - [最小费用最大流]
题目链接: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代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
const int INF=0x3f3f3f3f; struct Edge{
int u,v,cap,flow,cost;
};
struct MCMF
{
int s,t; //源点汇点
vector<Edge> E;
vector<int> G[maxn];
void init(int l,int r)
{
E.clear();
for(int i=l;i<=r;i++) G[i].clear();
}
void addedge(int from,int to,int cap,int cost)
{
E.push_back((Edge){from,to,cap,,cost});
E.push_back((Edge){to,from,,,-cost});
G[from].push_back(E.size()-);
G[to].push_back(E.size()-);
} int d[maxn],vis[maxn];
int aug[maxn],pre[maxn];
bool spfa(int s,int t,int &flow,int &cost)
{
memset(d,INF,sizeof(d));
memset(vis,,sizeof(vis));
queue<int> q;
q.push(s);
d[s]=, vis[s]=, pre[s]=, aug[s]=INF;
while(!q.empty())
{
int now=q.front(); q.pop();
vis[now]=;
for(int i=;i<G[now].size();i++)
{
Edge& e=E[G[now][i]]; int nxt=e.v;
if(e.cap>e.flow && d[nxt]>d[now]+e.cost)
{
d[nxt]=d[now]+e.cost;
pre[nxt]=G[now][i];
aug[nxt]=min(aug[now],e.cap-e.flow);
if(!vis[nxt])
{
q.push(nxt);
vis[nxt]=;
}
}
}
}
if(d[t]==INF) return ;
flow+=aug[t];
cost+=d[t]*aug[t];
for(int i=t;i!=s;i=E[pre[i]].u)
{
E[pre[i]].flow+=aug[t];
E[pre[i]^].flow-=aug[t];
}
return ;
} int mc,mf;
void solve()
{
int flow=,cost=;
while(spfa(s,t,flow,cost));
mc=cost;
mf=flow;
}
}mcmf; int n,m;
int a[],b[];
int main()
{
cin>>n>>m;
for(int i=;i<=n;i++) cin>>a[i]>>b[i]; mcmf.init(,n+n*m+);
mcmf.s=;
mcmf.t=n+n*m+;
for(int i=;i<=n;i++)
{
mcmf.addedge(mcmf.s,i,,);
for(int j=,u,v;j<=n;j++)
{
u=i,v=n+(a[i]-)*n+j;
mcmf.addedge(u,v,,*j-);
u=i,v=n+(b[i]-)*n+j;
mcmf.addedge(u,v,,*j-);
}
}
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
mcmf.addedge(n+(i-)*n+j,mcmf.t,,); mcmf.solve();
printf("%d\n",mcmf.mc);
}
nowcoder 206A - Birthday - [最小费用最大流]的更多相关文章
- HDU5988/nowcoder 207G - Coding Contest - [最小费用最大流]
题目链接:https://www.nowcoder.com/acm/contest/207/G 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5988 ...
- 2018牛客网暑期ACM多校训练营(第五场) E - room - [最小费用最大流模板题]
题目链接:https://www.nowcoder.com/acm/contest/143/E 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524288K ...
- 牛客2018多校第五场E-room 最小费用最大流
题意:有n个寝室,每个寝室4个人,现在在搞搬寝室的活动,告诉你每个寝室之前的人员名单,和之后的人员名单,问最少需要几个人要搬寝室. 思路: 转化为最小费用最大流解决的二分图问题,对每个去年的宿舍,向每 ...
- [板子]最小费用最大流(Dijkstra增广)
最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...
- bzoj1927最小费用最大流
其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→ =_=你TM逗我 刚要删突然感觉dinic的模 ...
- ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)
将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...
- HDU5900 QSC and Master(区间DP + 最小费用最大流)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...
- P3381 【模板】最小费用最大流
P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...
- 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)
3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 821 Solved: 502[Submit][Status ...
随机推荐
- 查看tar文件的顶层目录
方法一: tar -tf udpSocket.tar | awk -F "/" '{print $1}' | sort | uniq 方法二: tar -tf udpSocket. ...
- LaTeX 中使两张表格并排
在使用 LaTeX写论文或者画海报的时候,希望两张较小的表格可以并排,(一般情况的LaTeX插入两张图片是上下布局的) 查找了一下,相关的例子如下: \begin{minipage}{\textwid ...
- 【SqlServer】解析SqlServer的分页
方式1: 假设页数是10,现在要拿出第5页的内容,查询语句如下: --10代表分页的大小 * from test where id not in ( --40是这么计算出来的:10*(5-1) id ...
- [转]Java 反射在实际开发中的应用
一:Java类加载和初始化 1.1 类加载器(类加载的工具) 1.2 Java使用一个类所需的准备工作 二:Java中RTTI 2.1 :为什么要用到运行时类型信息(就是RTTI) 2.2 :RTT ...
- Android Studio配置文件路径修改
用Android Studio进行Android开发已经成为趋势了,好的工具要用得称手也少不了好的调教,在Windows下更是如此.这里对Android Studio的相关配置文件的路径修改做下小结. ...
- java8学习的一点总结
最近研究了一下java8 弄了几个例子学习了一下用法: 创建了一个实体类: @Data public class Apple { private Integer id; private String ...
- ESXi创建磁盘命令
[root@esx421 SAN]# vmkfstools -d thick -a lsilogic -c 10G lun00.vmdk Incorrect disk option "thi ...
- Opencv Mat运算(转)
一.矩阵Mat I,img,I1,I2,dst,A,B; double k,alpha; Scalar s; //注意Mat的行列号是从0开始的 //定义矩阵a,b,c Mat a,b,c; //生成 ...
- CentOS系统实现SSH无密码登录的方法
一.环境配置 1.服务端:CentOS release 5.3 IP:222.73.115.198 2.客服端:CentOS release 5.8 IP:192.168.4.244 二.配置SSH无 ...
- (原)关于i++和++i的小程序测试
今天看到一个程序,于是用vs运行了一下,结果出乎我的意料: 代码: ; +(i++))+(+(i++)); i=; +(++i))+(+(++i)); i=; printf("x=%d,y= ...