[Ahoi2014]支线剧情[无源汇有下界最小费用可行流]
3876: [Ahoi2014]支线剧情
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 1538 Solved: 940
[Submit][Status][Discuss]
Description
Input
Output
输出一行包含一个整数,表示JYY看完所有支线剧情所需要的最少时间。
Sample Input
2 2 1 3 2
2 4 3 5 4
2 5 5 6 6
0
0
0
Sample Output
HINT
JYY需要重新开始3次游戏,加上一开始的一次游戏,4次游戏的进程是
Source
题意:给定一个DAG,1为起始点,任意一个点可以直接回到1,每条边有经过代价,求一种最优方案使得每条边至少经过一次,代价最小。
暴力:枚举终点,非严格次短路更新。
时间复杂度:O(p*s*nlogn){p为终点数,s为1->一终点路径上点的出度的乘积,nlogn为堆优化的dijkstra的时间}
考虑极端情况:s可以达到2^n(可以想象成一个树,树根为1,叶子节点全都只连同一个节点)
显然:TLE
正解:无源汇有下界最小费用可行流。
具体建图如下:
对于x->y,费用为z
S向y建容量为1,费用为z的边(对应无源汇里的入度处理)
x向y建容量INF,费用为z的边(即自由流)
对于每一个点x,假设其出度为a
x向T建容量为a,费用为0的边(出度处理)(注意这里不要加上费用,因为已经在入度处理的时候就加过了)
x向1建容量INF,费用为0的边(对应题意)
然后跑最小费用流就可以了。
#include<cstdio>
#include<cstring>
#include<iostream>
#define EF if(ch==EOF) return x;
using namespace std;
const int N=5e4+;
const int inf=2e9;
struct data{int x,y;}f[N];
struct edge{int v,next,cap,cost;}e[N<<];int tot=,head[N];
int n,m,cnt,ans,S,T,rd[N],cd[N],dis[N],pre[N],q[N<<];bool vis[N];
inline int read(){
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;EF;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void add(int x,int y,int z,int cost=){
e[++tot].v=y;e[tot].cap=z;e[tot].cost=cost;e[tot].next=head[x];head[x]=tot;
e[++tot].v=x;e[tot].cap=;e[tot].cost=-cost;e[tot].next=head[y];head[y]=tot;
}
bool spfa(){
memset(vis,,sizeof vis);
memset(dis,0x3f,sizeof dis);
unsigned short h=,t=;q[t]=S;dis[S]=;vis[S]=;
while(h!=t){
int x=q[++h];vis[x]=;
for(int i=head[x];i;i=e[i].next){
if(e[i].cap&&dis[e[i].v]>dis[x]+e[i].cost){
dis[e[i].v]=dis[x]+e[i].cost;
pre[e[i].v]=i;
if(!vis[e[i].v]){
vis[e[i].v]=;
q[++t]=e[i].v;
}
}
}
}
return dis[T]<0x3f3f3f3f;
}
int augment(){
int flow=0x3f3f3f3f;
for(int i=T;i!=S;i=e[pre[i]^].v) flow=min(flow,e[pre[i]].cap);
for(int i=T;i!=S;i=e[pre[i]^].v){
e[pre[i]].cap-=flow;
e[pre[i]^].cap+=flow;
}
return dis[T]*flow;
}
void MCMF(){
while(spfa()) ans+=augment();
}
int main(){
n=read();S=,T=n+;
for(int i=,x,y,z;i<=n;i++){
x=read();cd[i]=x;
if(i!=) add(i,,inf);
while(x--) y=read(),z=read(),ans+=z,rd[y]++,add(i,y,inf,z);
}
for(int i=;i<=n;i++){
if(rd[i]>cd[i]) add(S,i,rd[i]-cd[i]);
else add(i,T,cd[i]-rd[i]);
}
MCMF();
printf("%d",ans);
return ;
}
实际上有一个很大的建图优化,也是无源汇建图的优化,即合并入出度并且相互抵消。但是对于这道题就不好做,因为有费用,不过可以这么想:既然每一条边都要走,我们就直接把费用抽出来,即答案一开始就为所有边走一次的代价,然后这样入度的费用就变为0了。然后再与出度进行抵消,最后边的数量大大减少。
[Ahoi2014]支线剧情[无源汇有下界最小费用可行流]的更多相关文章
- BZOJ 3876 支线剧情 有源汇有上下界最小费用可行流
题意: 给定一张拓扑图,每条边有边权,每次只能从第一个点出发沿着拓扑图走一条路径,求遍历所有边所需要的最小边权和 分析: 这道题乍一看,可能会想到什么最小链覆盖之类的,但是仔细一想,会发现不行,一是因 ...
- BZOJ 2055 80人环游世界 有上下界最小费用可行流
题意: 现在有这么一个m人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家. 因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第 ...
- hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )
题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...
- BZOJ 3876:支线剧情(有下界最小费用最大流)
3876: [Ahoi2014]支线剧情 Description [故事背景]宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧 ...
- BZOJ 3876 [AHOI/JSOI2014]支线剧情 (最小费用可行流)
题面:洛谷传送门 BZOJ传送门 题目大意:给你一张有向无环图,边有边权,让我们用任意条从1号点开始的路径覆盖这张图,需要保证覆盖完成后图内所有边都被覆盖至少一次,求覆盖路径总长度的最小值 最小费用可 ...
- ZOJ 2314 (无源汇有上下边界的可行流)
(点击此处查看原题) 题意分析 给出n个结点,m条管道,每条管道存在最小流量和最大流量,而且每个结点的流入量等于流出流出量,问这n个结点和m条管道能否形成流量循环 解题思路 经典的无源汇有上下边界的可 ...
- 【CF708D】Incorrect Flow 最小费用可行流
[CF708D]Incorrect Flow 题意:给你一个点数为n,边数为m的流网络,每条边有一个容量c和流量f,这个网络可能是不合法的.你可以花费1的代价使c或f减少或增加1,可以修改无限次.你不 ...
- BZOJ 3876 支线剧情(有上下界的无源汇最小费用可行流)
3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 1783 Solved: 1079 [Submit][St ...
- bzoj 3876 [Ahoi2014]支线剧情(有上下界的最小费用流)
3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 484 Solved: 296[Submit][Status ...
随机推荐
- dbutil组件的常见用法
该工具包主要用来操作数据库,进行增删改查.将结果包装到对象或对象集合中. 在写web项目的时候,经常会涉及到数据库的操作.比如连接数据库获取连接对象.执行sql语句.获得结果.如果对每一个方法都写这么 ...
- unity, public+[HideInInspector] vs private
下面写法不报错: [System.Serializable] public class CmyObj{ CA m_a; ... } public class XXX: MonoBehavior{ [H ...
- unity, mono断点
在unity编辑器中点运行后,如果直接在mono中打断点是不起作用的,需要再点击mono的run按钮,此时弹出Attach to Process对话框,如图: 选中其中的Unity Editor (U ...
- 源码分析:Java堆的创建
虚拟机在内存中申请一片区域,由虚拟机自动管理,用来满足应用程序对象分配的空间需求,即堆空间. 由于程序运行的局部特性,程序创建的大多数对象都具有非常短的生命周期,而程序也会创建一些生命周期特别长的对象 ...
- Struts2源码阅读(一)_Struts2框架流程概述
1. Struts2架构图 当外部的httpservletrequest到来时 ,初始到了servlet容器(所以虽然Servlet和Action是解耦合的,但是Action依旧能够通过httpse ...
- 李洪强iOS经典面试题35-按层遍历二叉树的节点
李洪强iOS经典面试题35-按层遍历二叉树的节点 问题 给你一棵二叉树,请按层输出其的节点值,即:按从上到下,从左到右的顺序. 例如,如果给你如下一棵二叉树: 3 / \ 9 20 ...
- iOS图片上传1
这几天在搞iphone上面一个应用的开发,里面有需要摄像头/相册编程和图片上传的问题,在这里总结一下. [部分知识] iphone中图像通常存储在4个地方[相册.应用程序包.沙盒.Internet], ...
- kafka启动及查看topic命令【已用过的,待更新】
以下均为开发测试环境下: 启动Zookeeperbin/zookeeper-server-start.sh config/zookeeper.properties &启动kafkabin/ka ...
- Linux IO实时监控iostat命令详解(转载)
简介 iostat主要用于监控系统设备的IO负载情况,iostat首次运行时显示自系统启动开始的各项统计信息,之后运行iostat将显示自上次运行该命令以后的统计信息.用户可以通过指定统计的次数和时间 ...
- 重置 ckeditor清空内容
转载自:http://blog.csdn.net/woshirongshaolin/article/details/8239407 <script type="text/javascr ...