题目链接: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 - [最小费用最大流]的更多相关文章

  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. CentOS---网络配置详解 (转)

    一.配置文件详解在RHEL或者CentOS等Redhat系的Linux系统里,跟网络有关的主要设置文件如下: /etc/host.conf         配置域名服务客户端的控制文件/etc/hos ...

  2. [svc]rsync简单部署

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

  3. Socket网络编程--epoll小结

    以前使用的用于I/O多路复用为了方便就使用select函数,但select这个函数是有缺陷的.因为它所支持的并发连接数是有限的(一般小于1024),因为用户处理的数组是使用硬编码的.这个最大值为FD_ ...

  4. 如何生成ExecutionGraph及物理执行图

    http://chenyuzhao.me/2017/02/06/flink%E7%89%A9%E7%90%86%E8%AE%A1%E5%88%92%E7%94%9F%E6%88%90/ https:/ ...

  5. linux每日命令(3):ln命令

    ln是linux中又一个非常重要命令,它的功能是为某一个文件在另外一个位置建立一个同步的链接.当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在 ...

  6. Centos 编译安装nodejs&express框架

    一. 下载nodejs 版本 wget http://nodejs.org/dist/v0.10.28/node-v0.10.28.tar.gz 二. 编译安装 cp node-v0.10.28.ta ...

  7. 学习MongoDB(三) Add an Arbiter to Replica Set 集群中加入仲裁节点

    Add an Arbiter to Replica Set 在集群中加入仲裁节点,当集群中主节点挂掉后负责选出新的主节点,仲裁节点也是一个mongo实力,但是它不存储数据. 1.仲裁节点消耗很小的资源 ...

  8. hdoj:2024

    #include <iostream> #include <string> #include <vector> using namespace std; int m ...

  9. Java知多少(14)数组

    如果希望保存一组有相同类型的数据,可以使用数组. 数组的定义和内存分配 Java 中定义数组的语法有两种: type arrayName[]; type[] arrayName; type 为Java ...

  10. R语言使用RMySQL连接及读写Mysql数据库

    简单说下安装过程,一般不会有问题,重点是RMySQL的使用方式. 系统环境说明 Redhat系统:Linux 460-42.6.32-431.29.2.el6.x86_64 系统编码:LANG=zh_ ...