题意:

       给以一个图,每个有向边都有两个权值,a,b其中a是保留这条边的花费,b是删除这条边的花费,让你删去一些边使图满足一下要求:

(1)只有一个起点和一个终点

(2)所有的边都是又向的(题目给的就是有向的)

(3)对于起点,出度 = 入度 + 1

(4)对于终点,入度 = 出度 + 1

(5)其他的点 出度 = 入度 

求满足要求时的花费最小。

 

思路:

      仔细一看要求,貌似是在求一个“欧拉路”,(但是图不一定是连通的),如果我们直接把t-s连起来就是在求所有出度=入度的最小了,也就是在求一些欧拉回路,第一反应以为是混合欧拉呢,但是对于混合欧拉是用流而不是费用流,而且混合欧拉里面也不设计到费用,但是他们有很大的相似之处,这个题目做了好久,是因为自己想不出来,同时网上的的解题报告很少,并且有的根本就写错了,还有就是网上没有说为什么,只有怎么建图,所以想了好久才明白,思路不怎么好说,我尽量去描述清楚,一边建图一遍说吧。

(1)对于每一条边,我们先选择a,b中最小的加在sum里

//先选择最小的,最为当前的选择,最后在用sum + 调整的代价就行了。

(2)如果a <= b   sum += a ,连接边b -> a,流量 1 ,费用b - a

//a小我们选择a,选择a也就是我们当前打算要这条边,此时我们建立b->a是为了反悔的时候用的,b - a 是因为反悔的时候要花费的代价是 b-a,因为有一部分是放在sum里了。

因为我们选择了这条边,此时还要记录度数,我们虽然建的是b->a但度数要这样,in[b]++,

out[a] ++,因为b->a是为了反悔用的,我们的决策是在图里建了一条a->b的边,所以度数是那样存的,不要弄混了。

(3)如果b < a  sum += b ,连接边a -> b,流量 1,费用a - b

// b小于a ,当前我们的选择是不连这条边,a -> b 是为了后悔的时候用的,后悔的时候我们只要在花费a - b就可以把不连变成连了,有一个关键地方就是对于这种决策不要计算入度和出度,因为我们选择的是不连边,所以当前的决策里面不设计到度数的改变。

(4)因为我们要把图处理成所有点的出度=入度,所以我们还得吧in[s] ++ ,out[t] ++,

记住只是改度数,而没有去连边,只是虚拟的去连边。

(5)最后我们要设立一个超级原点S和超级汇点T,对于所有点如果in[i] > out[i],

连接 S->i ,流量为in[i] - out[i] ,费用 0,否则连接i->T,流量out[i] - in[i],

费用0。

// 这个位置一定要理解好,不要和混合欧拉混了,混合欧拉是in[i] < out[i],连接

S->i,流量是 (out[i] - in[i]) / 2,混合欧拉是在调整(双向边的)涉及的度数,而咱们这个题目是为了调整单向边涉及的点的度数,并且含有代价在里面,至于为什么连接S-i,和i->T的时候和混合欧拉是反的,是因为我们组开始建图的时候建的都是反边,也就是建的都是反悔的时候才跑的边,所以涉及到反向。

为了理解这个题目我画了集合图来方便大家理解,画的垃圾忘谅解。


跑一边S->T的费用流就可以选择出事l1反悔还是l2反悔了,如果对于l1,l2都不选,那么和这个差不多,只不过是虚线的方向边了,S,T的连点再调换一下,如果都选我们跑边S->T的目的是为了找出我们选择的那一个,因为毕竟l1,l2我们要选一个丢弃一个,如果是在之前我们的去最小决策就正好选了一个,丢弃了一个,那么此时的连个点出度=入度,也就没必要跑费用流了。

下面是代码。


#include<stdio.h>
#include<string.h>
#include<queue> #define N_node 110
#define N_edge 5000
#define INF 1000000000

using namespace
std; typedef struct
{
int
from ,to ,next;
int
cost ,flow;
}
STAR; STAR E[N_edge];
int
list[N_node] ,tot;
int
s_x[N_node];
int
mer[N_edge];
int
in[N_node] ,out[N_node]; void add(int a ,int b ,int c ,int d)
{

E[++tot].from = a;
E[tot].to = b;
E[tot].cost = c;
E[tot].flow = d;
E[tot].next = list[a];
list[a] = tot; E[++tot].from = b;
E[tot].to = a;
E[tot].cost = -c;
E[tot].flow = 0;
E[tot].next = list[b];
list[b] = tot;
} bool
SPFA(int s ,int t ,int n)
{
for(int
i = 0 ;i <= n ;i ++)
s_x[i] = INF;
int
mark[N_node] = {0};
s_x[s] = 0;
mark[s] = 1;
queue<int>q;
q.push(s);
memset(mer ,255 ,sizeof(mer));
while(!
q.empty())
{
int
xin ,tou;
tou = q.front();
q.pop();
mark[tou] = 0;
for(int
k = list[tou] ;k; k = E[k].next)
{

xin = E[k].to;
if(
s_x[xin] > s_x[tou] + E[k].cost && E[k].flow)
{

s_x[xin] = s_x[tou] + E[k].cost;
mer[xin] = k;
if(!
mark[xin])
{

mark[xin] = 1;
q.push(xin);
}
}
}
}
return
mer[t] != -1;
} int
MCMF_Spfa(int s ,int t ,int n ,int ss)
{
int
maxflow ,mincost ,minflow;
maxflow = mincost = 0;
while(
SPFA(s ,t ,n))
{

minflow = INF;
for(int
i = mer[t] ;i + 1 ;i = mer[E[i].from])
{
if(
minflow > E[i].flow)
minflow = E[i].flow;
}
for(int
i = mer[t] ;i + 1 ;i = mer[E[i].from])
{

E[i].flow -= minflow;
E[i^1].flow += minflow;
mincost += E[i].cost * minflow;
}

maxflow += minflow;
}
if(
maxflow != ss) return -1;
return
mincost;
} int main ()
{
int
tt ,n ,m ,s ,t ,S ,T ,i;
int
cas = 1;
int
a ,b ,c ,d;
scanf("%d" ,&tt);
while(
tt--)
{

scanf("%d %d %d %d" ,&n ,&m ,&s ,&t);
S = 0 ,T = n + 1;
memset(list ,0 ,sizeof(list));
tot = 1;
memset(in ,0 ,sizeof(in));
memset(out ,0 ,sizeof(out));
in[s] ++ ,out[t] ++;
int
sum = 0;
for(
i = 1 ;i <= m ;i ++)
{

scanf("%d %d %d %d" ,&a ,&b ,&c ,&d);
if(
c <= d)
{

add(b ,a ,d - c ,1);
sum += c;
in[b]++ ,out[a] ++;
}
else
{

add(a ,b ,c - d ,1);
sum += d;
}
}
int
ss = 0 ,sss = 0;
for(
i = 1 ;i <= n ;i ++)
{
if(
in[i] >= out[i])
{

add(S ,i ,0 ,in[i] - out[i]);
ss += (in[i] - out[i]);
}
else
{

add(i ,T ,0 ,out[i] - in[i]);
sss += (out[i] - in[i]);
}
}
int
ans = MCMF_Spfa(S ,T ,n + 1 ,ss);
printf("Case %d: " ,cas ++);
if(
ans == -1 || ss != sss)puts("impossible");
else
printf("%d\n" ,ans + sum);
}
return
0;
}




hdu4067 费用流(混合欧拉的宽展和延伸)的更多相关文章

  1. hdu3472 混合欧拉

    题意:       给你一些字符串,有的字符串反过来也有意义,题目问给的这n个字符串是否可以首尾相连,组成一个串. 思路:       算是混合欧拉的基础题目了,混合欧拉就是专门处理这类问题的,先说下 ...

  2. [bzoj3308]九月的咖啡店_欧拉筛素数_费用流

    bzoj-3308 九月的咖啡店 题目大意:深绘里在九份开了一家咖啡让,如何调配咖啡民了她每天的头等大事我们假设她有N种原料,第i种原料编号为i,调配一杯咖啡则需要在这里若干种兑在一起.不过有些原料不 ...

  3. hdu3472 混合图判断欧拉通路

    对于欧拉回路,先判断出度入度的差是否为偶数,然后最大流一次. 此题是判断有无欧拉通路,前提要判断图是否连通,然后欧拉通路的条件:要么出入度差没有奇数,或者只有2个点. 所以先统计差为奇数的个数,如果不 ...

  4. HDU 4744 Starloop System(ZKW费用流)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4744 题意:三维空间n个点,每个点有一个wi值.每对点的距离定义为floor(欧拉距离),每对点之间建 ...

  5. Euler-Maruyama discretization("欧拉-丸山"数值解法)

    欧拉法的来源 在数学和计算机科学中,欧拉方法(Euler method)命名自它的发明者莱昂哈德·欧拉,是一种一阶数值方法,用以对给定初值的常微分方程(即初值问题)求解.它是一种解决常微分方程数值积分 ...

  6. [WC2007]剪刀石头布——费用流

    比较有思维含量的一道题 题意:给混合完全图定向(定向为竞赛图)使得有最多的三元环 三元环条件要求比较高,还不容易分开处理. 正难则反 考虑,什么情况下,三元组不是三元环 一定是一个点有2个入度,一个点 ...

  7. 网络流小记(EK&dinic&当前弧优化&费用流)

    欢 迎 来 到 网 络 瘤 的 世 界 什么是网络流? 现在我们有一座水库,周围有n个村庄,每个村庄都需要水,所以会修水管(每个水管都有一定的容量,流过的水量不能超过容量).最终水一定会流向唯一一个废 ...

  8. hdu2588 GCD (欧拉函数)

    GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数.  (文末有题) 知 ...

  9. BZOJ 2705: [SDOI2012]Longge的问题 [欧拉函数]

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 2553  Solved: 1565[Submit][ ...

随机推荐

  1. [MIT 18.06 线性代数]Intordution to Vectors向量初体验

    目录 1.1. Vectors and Linear Combinations向量和线性组合 REVIEW OF THE KEY IDEAS 1.2 Lengths and Dot Products向 ...

  2. 你好,布尔玛!(BulmaRazor)

    Blazor 官方简介 Blazor 是一个使用 .NET 生成交互式客户端 Web UI 的框架: 使用 C# 代替 JavaScript 来创建信息丰富的交互式 UI. 共享使用 .NET 编写的 ...

  3. c++:一个辅助类让内存泄漏现原形!

    前言 对于c++而言,如何查找内存泄漏是程序员亘古不变的话题:解决之道可谓花样繁多.因为最近要用到QT写程序,摆在我面前的第一个重要问题是内存防泄漏.如果能找到一个简单而行之有效的方法,对后续开发大有 ...

  4. cve-2019-2725 反序列化远程代码执行

    描述:部分版本WebLogic中默认包含的wls9_async_response包,为WebLogic Server提供异步通讯服务.由于该WAR包在反序列化处理输入信息时存在缺陷,攻击者可以发送精心 ...

  5. Flutter教程- Dart语言规范-知识点整理

    Flutter教程- Dart语言知识点整理 Dart语言简介 Dart语言介绍 ① 注释的方式 ② 变量的声明 ③ 字符串的声明和使用 ④ 集合变量的声明 ⑤ 数字的处理 ⑥ 循环的格式 ⑦ 抛异常 ...

  6. Python深入:setuptools进阶

    作者:gqtcgq 来源:CSDN 原文:https://blog.csdn.net/gqtcgq/article/details/49519685 Setuptools是Python Distuti ...

  7. Linux入门视频笔记一(基本命令)

    一.简单命令 1.date:当前时间 2.cal:当前日期(日历格式) ①cal 2019:2019年全年日历 ②cal 1 2019:2019年1月份 二.Linux文件结构 1.根目录:root( ...

  8. ES核心概念和原理

    ES:1:倒排索引 基于Document 关键词索引实现 . 根据关键词做索引 相关度 a. 数据结构 i. 包含关键词的Document List ii. 关键词在每个doc中出现的次数 词频 TF ...

  9. 亲自动手实现Python+pygame中国象棋游戏

    功能1:实现游戏整体界面显示 一.创建基本的结构 代码如下: import time import pygame def main(): # 初始化pygame pygame.init() # 创建用 ...

  10. OO第一单元总结与反思

    OO第一单元总结与反思 目录 OO第一单元总结与反思 摘要 第一次作业 本次作业UML类图 本次作业度量分析 第二次作业 本次作业的UML类图 本次作业的度量分析 第三次作业 本次作业的UML类图: ...