// 给定一个有向图,必须用若干个环来覆盖整个图,要求这些覆盖的环的权值最小。

思路:原图每个点 u 拆为 u 和 u' ,从源点引容量为 1 费用为 0 的边到 u ,从 u' 引相同性质的边到汇点,若原图中存在 (u, v) ,则从 u 引容量为 1 费用为 c(u, v) 的边到 v' 。

其实这里的源模拟的是出度,汇模拟的是入度,因为环中每个点的出度等于入度等于 1 ,那么如果最大流不等于顶点数 n ,则无解;否则,答案就是最小费用。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <queue> using namespace std; const int maxn = 2e2 + ;
const int maxm = 2e4 + ;
const int inf = 0x3f3f3f3f; struct MCMF
{
struct Edge
{
int v, c, w, next;
}p[maxm << ];
int e, head[maxn], dis[maxn], pre[maxn], cnt[maxn], sumFlow, n;
bool vis[maxn];
void init(int nt)
{
e = , n = nt;
memset(head, -, sizeof(head[]) * (n + ) );
}
void addEdge(int u, int v, int c, int w)
{
p[e].v = v, p[e].c = c; p[e].w = w; p[e].next = head[u]; head[u] = e++;
swap(u, v);
p[e].v = v, p[e].c = ; p[e].w = -w; p[e].next = head[u]; head[u] = e++;
}
bool spfa(int S, int T)
{
queue <int> q;
for (int i = ; i <= n; ++i)
vis[i] = cnt[i] = , pre[i] = -, dis[i] = inf;
vis[S] = , dis[S] = ;
q.push(S);
while (!q.empty())
{
int u = q.front(); q.pop();
vis[u] = ;
for (int i = head[u]; i + ; i = p[i].next)
{
int v = p[i].v;
if (p[i].c && dis[v] > dis[u] + p[i].w)
{
dis[v] = dis[u] + p[i].w;
pre[v] = i;
if (!vis[v])
{
q.push(v);
vis[v] = ;
if (++cnt[v] > n) return ;
}
}
}
}
return dis[T] != inf;
}
int mcmf(int S, int T)
{
sumFlow = ;
int minFlow = , minCost = ;
while (spfa(S, T))
{
minFlow = inf + ;
for (int i = pre[T]; i + ; i = pre[ p[i ^ ].v ])
minFlow = min(minFlow, p[i].c);
sumFlow += minFlow;
for (int i = pre[T]; i + ; i = pre[ p[i ^ ].v ])
{
p[i].c -= minFlow;
p[i ^ ].c += minFlow;
}
minCost += dis[T] * minFlow;
}
return minCost;
}
void build(int nt, int mt)
{
init((nt << ) + );
int u, v, c;
for (int i = ; i <= nt; ++i)
{
addEdge(, i, , );
addEdge(i + nt, n, , );
}
while (mt--)
{
scanf("%d%d%d", &u, &v, &c);
addEdge(u, v + nt, , c);
}
}
void solve(int nt)
{
int ans = mcmf(, n);
if ( sumFlow != nt)
printf("-1\n");
else
printf("%d\n", ans);
}
}my; int main()
{
int n, m;
while (~scanf("%d%d", &n, &m))
{
my.build(n, m);
my.solve(n);
}
return ;
}

hdu 1853 (费用流 拆点)的更多相关文章

  1. Going Home HDU - 1533 费用流

    http://acm.hdu.edu.cn/showproblem.php?pid=1533 给一个网格图,每两个点之间的匹配花费为其曼哈顿距离,问给每个的"$m$"匹配到一个&q ...

  2. HDU 3376 费用流 Matrix Again

    题意: 给出一个n × n的矩阵,每个格子中有一个数字代表权值,找出从左上角出发到右下角的两条不相交的路径(起点和终点除外),使得两条路径权值之和最大. 分析: 如果n比较小的话是可以DP的,但是现在 ...

  3. hdu 4406 费用流

    这题问题就是当前时刻究竟选择哪门课程,易知选择是和分数有关的,而且是一个变化的权值,所以能够用拆点的方式,把从基础分到100分都拆成点.但若这样拆点的话,跑费用流时就必须保证顺序.这样就麻烦了..观察 ...

  4. hdu 5045 费用流

    滚动建图,最大费用流(每次仅仅有就10个点的二分图).复杂度,m/n*(n^2)(n<=10),今年网络赛唯一网络流题,被队友状压DP秒了....难道网络流要逐渐退出历史舞台???.... #i ...

  5. hdu 2686 费用流 / 双线程DP

    题意:给一个方阵,求从左上角出到右下角(并返回到起点),经过每个点一次不重复,求最大获益(走到某处获得改点数值),下来时每次只能向右或向下,反之向上或向左. 俩种解法: 1  费用流法:思路转化:从左 ...

  6. hdu 4289 最大流拆点

    大致题意:     给出一个又n个点,m条边组成的无向图.给出两个点s,t.对于图中的每个点,去掉这个点都需要一定的花费.求至少多少花费才能使得s和t之间不连通. 大致思路:     最基础的拆点最大 ...

  7. HDU 3667 费用流 拆边 Transportation

    题意: 有N个城市,M条有向道路,要从1号城市运送K个货物到N号城市. 每条有向道路<u, v>运送费用和运送量的平方成正比,系数为ai 而且每条路最多运送Ci个货物,求最小费用. 分析: ...

  8. HDU 3667 费用流(拆边)

    题意:有n个城市(1~n),m条有向边:有k件货物要从1运到n,每条边最多能运c件货物,每条边有一个危险系数ai,经过这条路的费用需要ai*x2(x为货物的数量),问所有货物安全到达的费用. 思路:c ...

  9. HDU - 4780费用流

    题意:M台机器要生产n个糖果,糖果i的生产区间在(si, ti),花费是k(pi-si),pi是实际开始生产的时间机器,j从初始化到生产糖果i所需的时间Cij,花费是Dij,任意机器从生产糖果i到生产 ...

随机推荐

  1. Download FFmpeg

    Builds Static builds provide one self-contained .exe file for each program (ffmpeg, ffprobe, ffplay) ...

  2. css水平竖直居中方式

    CSS水平和垂直居中的几种实现方法: 1.单行垂直居中 文字在层中垂直居中vertical-align 属性是做不到的.我们这里有个比较巧妙的方法就是:设置height的高度与line-height的 ...

  3. Python 类的特殊成员方法详解

    class doges(object): """类的描述信息""" def __init__(self,name,food): self.n ...

  4. css - margin-padding

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. web报表工具FineReport经常使用函数的使用方法总结(日期和时间函数)

    web报表工具FineReport经常使用函数的使用方法总结(日期和时间函数) 说明:凡函数中以日期作为參数因子的,当中日期的形式都必须是yy/mm/dd.并且必须用英文环境下双引號(" & ...

  6. 解决Linux下3T硬盘分区只有2T(2199G)可用

    分区转换成GPT即可 sudo parted /dev/sdb 将MBR硬盘格式化为GPT mklabel gpt 之后可以看一下状态 print 整个硬盘空间只分一个区 mkpart primary ...

  7. <转>C++位运算详解

    原文转自:http://www.crazycpp.com/?p=82 前言 以前收藏过一篇讲C++位操作的文章,这次博客搬家,以前的数据都没有保留,整理谷歌网站管理后台的时候,发现不时的还有网友有在查 ...

  8. RandomForest 调参

    在scikit-learn中,RandomForest的分类器是RandomForestClassifier,回归器是RandomForestRegressor,需要调参的参数包括两部分,第一部分是B ...

  9. 用户输入URL后发生了什么,以及优化问题

    用户角度:1.打开浏览器2.输入URL3.按下回车4.浏览器呈现画面 当用户输入页面地址后,浏览器获得用户希望访问的地址,便向该站点服务器发起一系列的请求,这些请求不光包括对页面的请求,还包括对页面中 ...

  10. Atitit eclipse新特性总结3.1---4.4  4.5

    Atititeclipse新特性总结3.1---4.4  4.5 1. Eclipse 4.4 Luna正式发布了.1 1.1. 新版本的Eclipse默认对Java8提供支持1 1.2. 内存分析器 ...