~~~题面~~~

题解:

第一眼费用流,,然后想了好久怎么建图,,,最后发现是最小费用可行流的板子题。。。。

其实还没有很懂这个算法,所以这里只是摆一下步骤,以后再补理解吧。

首先一个思路就是转换图,将有上下限的图变为普通的网络流图,然后再跑费用流。

所以建图其实和有上下界的网络流一样的。。。

1,首先建立超级源点汇点ss和tt

2,对于原图中每一条边x ---> y,设其上下界为(l, r),费用为cost,那么连边的时候将流量变为r - l即可

3,对于任意点i,记d[i]为它的富余流量,即入度的下界和 - 出度的下界和。

  若d[i] > 0,则连边ss ----> i, 流量为d[i] , 费用0

  若d[i] < 0,则连边i ----> tt,流量为-d[i],费用0

4,连边t ---> s,流量inf,费用0

答案即为ans + 所有边下界 * 边的费用

其实可以感性的理解为先有了一个不一定合法的解(下界*费用),然后再利用费用流使用最小的代价使得答案合法。

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 400
#define ac 100000
#define inf 2139062143
#define getchar() *o++
char READ[], *o = READ;
int n, ans, s, t1, t;
int last[AC], dis[AC], disflow[AC], d[AC];
int date[ac], Next[ac], haveflow[ac], cost[ac], Head[AC], tot = ;
bool z[AC];
deque<int> q; inline int read()
{
int x=;char c=getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline void add(int f,int w,int S,int C)
{
date[++tot] = w, Next[tot] = Head[f], haveflow[tot] = S, cost[tot] = C, Head[f] = tot;
date[++tot] = f, Next[tot] = Head[w], cost[tot] = -C, Head[w] = tot;
//printf("%d %d %d %d\n",f,w,S,C);
} void pre()
{
int a,b,c;
n=read();
t1 = n + , s = n + , t = n + ;
for(R i=;i<=n;i++)
{
a=read();
for(R j=;j<=a;j++)
{
b=read(),c=read();
--d[i], ++d[b];
ans += c;
add(i, b, inf, c);
}
}
for(R i=;i<=n;i++)
add(i, t1, inf, );
for(R i=;i<=n;i++)
{
if(d[i] > ) add(s, i, d[i], );
if(d[i] < ) add(i, t, -d[i], );
}
add(t1, , inf, );//是费用为0!
} inline void aru()
{
int x = t;
while(x != s)
{
haveflow[last[x]] -= disflow[t];
haveflow[last[x] ^ ] += disflow[t];
x = date[last[x] ^ ];
}
ans += disflow[t] * dis[t];
} bool spfa()
{
int x, now;
dis[s] = , disflow[s] = inf, z[s] = true;
q.push_front(s);
while(!q.empty())
{
x = q.front();
q.pop_front();
z[x] = false;//标记出列
for(R i=Head[x]; i ;i=Next[i])
{
now = date[i];
if(haveflow[i] && dis[now] > dis[x] + cost[i])
{//要有流量啊
dis[now] = dis[x] + cost[i];
last[now] = i;
disflow[now] = min(disflow[x], haveflow[i]);
if(!z[now])
{
z[now] = true;
if(!q.empty() && dis[now] < q.front()) q.push_front(now);
else q.push_back(now);
}
}
}
}
if(dis[t] != inf) aru();
return dis[t] != inf;
} bool spfa1()
{
int x,now;
z[s]=true,dis[s]=,disflow[s]=inf;
q.push_front(s);
while(!q.empty())
{
x=q.front();
q.pop_front();
z[x]=false;
for(int i=Head[x]; i ;i=Next[i])
{
now=date[i];
if(haveflow[i] && dis[now]>dis[x]+cost[i])
{
dis[now]=dis[x]+cost[i];
last[now]=i;
disflow[now]=min(disflow[x],haveflow[i]);//以点为单位记录到这个点时的流量
if(!z[now])
{
z[now] = true;
q.push_front(now);
}
/*if(!z[now] && now!=t)
{
if(!q.empty() && dis[now]<dis[q.front()]) q.push_front(now);
else q.push_back(now);
z[now]=true;
}*/
}
}
}
//更新路径
if(dis[t] != inf) aru();
return dis[t] != inf;
} void work()
{
//printf("%d\n",ans);
memset(dis, , sizeof(dis));
while(spfa())
memset(dis, , sizeof(dis));
printf("%d\n",ans);
} int main()
{
// freopen("in.in","r",stdin);
fread(READ, , , stdin);
pre();
work();
// fclose(stdin);
return ;
}

[AHOI2014/JSOI2014]支线剧情 有上下界费用流的更多相关文章

  1. bzoj3876: [Ahoi2014&Jsoi2014]支线剧情(上下界费用流)

    传送门 一道题让我又要学可行流又要学zkw费用流…… 考虑一下,原题可以转化为一个有向图,每次走一条路径,把每一条边都至少覆盖一次,求最小代价 因为一条边每走过一次,就要付出一次代价 那不就是费用流了 ...

  2. 【BZOJ3876】[Ahoi2014]支线剧情 有上下界费用流

    [BZOJ3876][Ahoi2014]支线剧情 Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩 ...

  3. BZOJ3876[Ahoi2014&Jsoi2014]支线剧情——有上下界的最小费用最大流

    题目描述 [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现在JYY想花费 ...

  4. BZOJ3876 AHOI/JSOI2014支线剧情(上下界网络流)

    原图所有边下界设为1上界设为inf花费为时间,那么显然就是一个上下界最小费用流了.做法与可行流类似. 因为每次选的都是最短路增广,且显然不会有负权增广路,所以所求出来的可行流的费用就是最小的. #in ...

  5. BZOJ 3876: [Ahoi2014]支线剧情 [上下界费用流]

    3876: [Ahoi2014]支线剧情 题意:每次只能从1开始,每条边至少经过一次,有边权,求最小花费 裸上下界费用流...每条边下界为1就行了 注意要加上下界*边权 #include <io ...

  6. 【有源汇上下界费用流】BZOJ 3876 [Ahoi2014]支线剧情

    题目链接: http://www.lydsy.com:808/JudgeOnline/problem.php?id=3876 题目大意: 给定一张拓扑图(有向无环图),每条边有边权,每次只能从第一个点 ...

  7. bzoj3876: [Ahoi2014&Jsoi2014]支线剧情

    题意:给一幅图,从1开始,每条边有边权最少走一遍,可以在任意点退出,问最小花费 题解:上下界费用流,每个边都流一遍,然后为了保证流量平衡,新建源点汇点,跑费用流把流量平衡 /************* ...

  8. BZOJ.1927.[SDOI2010]星际竞速(无源汇上下界费用流SPFA /最小路径覆盖)

    题目链接 上下界费用流: /* 每个点i恰好(最少+最多)经过一次->拆点(最多)+限制流量下界(i,i',[1,1],0)(最少) 然后无源汇可行流 不需要源汇. 注: SS只会连i',求SS ...

  9. BZOJ2324 ZJOI2011营救皮卡丘(floyd+上下界费用流)

    虽然不一定每次都是由编号小的点向编号大的走,但一个人摧毁的顺序一定是从编号小的到编号大的.那么在摧毁据点x的过程中,其只能经过编号小于x的点.并且这样一定合法,因为可以控制其他人先去摧毁所经过的点.那 ...

随机推荐

  1. JS学习 用 arguments 对象模拟函数重载

    用 arguments 对象判断传递给函数的参数个数,即可模拟函数重载: function doAdd() { if(arguments.length == 1) { alert(arguments[ ...

  2. Ubuntu主题美化篇

    主题美化篇 Ubuntu自带的主题简直不敢恭维,这里博主将它美化了一番,心情瞬间都好了一大截,码代码也会飞起!!先放一张我美化后的效果. 桌面和终端效果如下: unity-tweak-tool 调整 ...

  3. Android Test和Logcat

    一 测试相关概念 是否有源码 黑盒测试: 测试工具 白盒测试: 对所有的源码特别熟悉 对特定的代码进行测试 都是编程 时间 单元测试(程序员) 模块测试 集成测试 系统测试 回归测试(改bug) 压力 ...

  4. Soliworks 2016建模细节总结(1)

    Soliworks 2016建模小细节总结(1) 1.Solidworks 2016三维建模的时候,如果想要在一个视图里面呈现出四个视图(包括三个独立的视图以及三维结构的实体模型图),可以直接按鼠标会 ...

  5. GIT: 分布式开发 代码管理工具使用命令大全

    代码管理工具: GIT     什么是GIT? Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目 Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常 ...

  6. mouseover 和 mouseout 事件是可以冒泡的 取消

    mouseover 和 mouseout 事件是可以冒泡的,子元素上触发的事件会冒泡到父元素上.可以改用 mouseleave 和 mouseenter 事件,这两个事件不冒泡.

  7. 我的Vscode配置

    "editor.fontSize": 17,//字体大小 "editor.wordWrap": "on",//软换行 "files ...

  8. 《剑指Offer》题三十一~题四十

    三十一.栈的压入.弹出序列 题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的数字均不相等.例如,序列{1, 2, 3, 4 ,5}是某栈的压栈序列 ...

  9. Thunder团队第二周 - Scrum会议1

    Scrum会议1 小组名称:Thunder 项目名称:爱阅app Scrum Master:王航 工作照片: 参会成员: 王航(Master):http://www.cnblogs.com/wangh ...

  10. Daily Scrum8

    今天我们小组开会内容分为以下部分: part 1: 说明了search.match.upload.download功能实现流程: part 2:针对用户积分模块的任务分配: ◆Part 1 searc ...