【BZOJ】【2324】【ZJOI2011】拯救皮卡丘
网络流/费用流+Floyed
Orz zyf
题解:
这题和星际竞速还有打印机两题的主体思路都是一样的
每个点一定要经过,并且要经过这个点,必须经过比这个点小的所有点。而且还存在一个附加源,但源到附加源有一定的容量限制(星际没有。。。)
这题我们采用如下方式建图:
1.把每个点拆成 i 和 i+n 两个点,分别表示从这个点出发和进入这个点
2.由s向所有i 连容量为1,费用为0的边
2.由所有i+n到t连容量为1,费用为0的边
3.由 i 向所有 j+n(j>n)连容量为1,费用为从 i 到 j,不经过比j标号大的中间节点的最短路 的边 (否则这条道路将不合法)
正确性可以从i+n 入流的来源来考虑,每一种流法都代表着一种实实在在的、合法的方案,cost就是花费时间,我们要时间最短,自然要最小费用最大流了
还有一个问题就是
费用为从 i 到 j,不经过比j标号大的中间节点的最短路 怎么求?
我自己yy了一种想法,如下:
- for(int k=0;k<=n;k++)
- for(int i=0;i<=n;i++)
- for(int j=k;j<=n;j++)
- f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
意思就是不使用比 j 大的节点作为中间节点来更新 i(1..n)到j的最短路
所以这个过程结束后,f[i][j]就代表着从 i 到 j不经过比 j大的节点的最短路
这种每个点都要经过一遍的题目好像都可以拆点搞二分图模型?
- /**************************************************************
- Problem: 2324
- User: Tunix
- Language: C++
- Result: Accepted
- Time:196 ms
- Memory:6052 kb
- ****************************************************************/
- //BZOJ 2324
- #include<vector>
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<iostream>
- #include<algorithm>
- #define rep(i,n) for(int i=0;i<n;++i)
- #define F(i,j,n) for(int i=j;i<=n;++i)
- #define D(i,j,n) for(int i=j;i>=n;--i)
- #define pb push_back
- using namespace std;
- inline int getint(){
- int v=,sign=; char ch=getchar();
- while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
- while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
- return v*sign;
- }
- const int N=,M=,INF=~0u>>;
- typedef long long LL;
- /******************tamplate*********************/
- int n,m,k,mp[][];
- LL ans;
- struct edge{int from,to,v,c;};
- struct Net{
- edge E[M];
- int head[N],next[M],cnt;
- void ins(int x,int y,int z,int c){
- E[++cnt]=(edge){x,y,z,c};
- next[cnt]=head[x]; head[x]=cnt;
- }
- void add(int x,int y,int z,int c){
- ins(x,y,z,c); ins(y,x,,-c);
- }
- int from[N],Q[M],d[N],S,T,ss;
- bool inq[N];
- bool spfa(){
- int l=,r=-;
- F(i,,T) d[i]=INF;
- d[S]=; Q[++r]=S; inq[S]=;
- while(l<=r){
- int x=Q[l++];
- inq[x]=;
- for(int i=head[x];i;i=next[i])
- if(E[i].v> && d[x]+E[i].c<d[E[i].to]){
- d[E[i].to]=d[x]+E[i].c;
- from[E[i].to]=i;
- if (!inq[E[i].to]){
- Q[++r]=E[i].to;
- inq[E[i].to]=;
- }
- }
- }
- return d[T]!=INF;
- }
- void mcf(){
- int x=INF;
- for(int i=from[T];i;i=from[E[i].from])
- x=min(x,E[i].v);
- for(int i=from[T];i;i=from[E[i].from]){
- E[i].v-=x;
- E[i^].v+=x;
- }
- ans+=x*d[T];
- }
- void init(){
- n=getint(); m=getint(); k=getint();
- cnt=;ans=;
- int x,y,z;
- F(i,,n)F(j,,n) mp[i][j]=INF;
- F(i,,m){
- x=getint(); y=getint(); z=getint();
- mp[x][y]=min(mp[x][y],z);
- mp[y][x]=min(mp[y][x],z);
- }
- S=; ss=*n+; T=*n+; add(S,ss,k,);
- F(k,,n) F(i,,n) F(j,k,n)
- mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
- F(i,,n) add(S,i,,),
- add(ss,i+n,,mp[][i]),
- add(i+n,T,,);
- F(i,,n) F(j,i+,n)
- add(i,j+n,,mp[i][j]);
- while(spfa()) mcf();
- printf("%lld\n",ans);
- }
- }G1;
- int main(){
- #ifndef ONLINE_JUDGE
- freopen("2324.in","r",stdin);
- freopen("2324.out","w",stdout);
- #endif
- G1.init();
- return ;
- }
【BZOJ】【2324】【ZJOI2011】拯救皮卡丘的更多相关文章
- bzoj 2324 [ZJOI2011]营救皮卡丘(floyd,费用流)
2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1777 Solved: 712[Submit][Stat ...
- BZOJ 2324: [ZJOI2011]营救皮卡丘( floyd + 费用流 )
昨晚写的题...补发一下题解... 把1~N每个点拆成xi, yi 2个. 预处理i->j经过编号不超过max(i,j)的最短路(floyd) S->0(K, 0), S->xi(1 ...
- BZOJ.2324.[ZJOI2011]营救皮卡丘(费用流 Floyd)
BZOJ 洛谷 首先预处理出\(dis[i][j]\),表示从\(i\)到\(j\)的最短路.可以用\(Floyd\)处理. 注意\(i,j\)是没有大小关系限制的(\(i>j\)的\(dis[ ...
- bzoj 2324: [ZJOI2011]营救皮卡丘
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #inclu ...
- BZOJ 2324: [ZJOI2011]营救皮卡丘(带上下限的最小费用最大流)
这道题么= =还是有些恶心的,第一次写带上下界的网络流,整个人都萌萌哒~~~ 首先先预处理得最短路后 直接用费用流做就行了。 第一次写,还是挺好写的= = CODE: #include<cstd ...
- bzoj 2324 ZJOI 营救皮卡丘 费用流
题的大概意思就是给定一个无向图,边有权值,现在你有k个人在0点,要求走到n点,且满足 1:人们可以分头行动,可以停在某一点不走了 2:当你走到x时,前x-1个点必须全部走过(不同的人走过也行,即分两路 ...
- BZOJ2324: [ZJOI2011]营救皮卡丘
2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1359 Solved: 522[Submit][Stat ...
- 【BZOJ2324】[ZJOI2011]营救皮卡丘(网络流,费用流)
[BZOJ2324][ZJOI2011]营救皮卡丘(网络流,费用流) 题面 BZOJ 洛谷 题解 如果考虑每个人走的路径,就会很麻烦. 转过来考虑每个人破坏的点集,这样子每个人可以得到一个上升的序列. ...
- 【BZOJ2324】[ZJOI2011]营救皮卡丘 有上下界费用流
[BZOJ2324][ZJOI2011]营救皮卡丘 Description 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的 ...
- bzoj2324 [ZJOI2011]营救皮卡丘 费用流
[ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2653 Solved: 1101[Submit][Status][D ...
随机推荐
- Silverlight 使用IsolatedStorage新建XML文件,并且用LINQ查询XML
代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-- ...
- Entity Framework 5问题集锦
ORM框架万万千,一直都使用NHibernate,没用过其他的.最近闲来学习下微软自家的Entity Framework,记录一些我学习过程中遇到的头疼问题.(不断更新中...) 教程:http:// ...
- mac虚拟机parallels 无法启动 "Windows 7" 虚拟机
关机前在虚拟机上安装了个游戏有点大,第二天开机就使用不了虚拟机了: 提示:mac虚拟机parallels 无法启动 "Windows 7" 虚拟机. 释放至少 241 MB 的 ...
- MySQL远程访问授权
开启 MySQL 的远程登陆帐号有两大步: 1.确定服务器上的防火墙没有阻止 3306 端口. MySQL 默认的端口是 3306 ,需要确定防火墙没有阻止 3306 端口,否则远程是无法通过 330 ...
- PHP JS HTML ASP页面跳转代码 延时跳转代码
1.PHP延时跳转代码 //跳转到浏览界面 header("Refresh:1;url=machine_list.php"); //不延时 <?php header(&quo ...
- C语言中的堆与栈20160604
首先声明这里说的是C语言中的堆与栈,并不是数据结构中的!一.前言介绍:C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件是静态区域由代码段和数据段(由二部分部分组成:只读数据 段,未初始化数 ...
- 编写可维护的JavaScript之简易模版
/* * 正则替换%s * @para arg1(text) 需要替换的模版 * @para arg2 替换第一处%s * @para arg3 替换第二处%s * 返回替换后的字符串 */ var ...
- find用法
find - 递归地在层次目录中处理文件 总 find [path...] [expression] 描 这个文档是GNU版本 find 命令的使用手册. find 搜索目录树上的每一个文件名,它从左 ...
- 52.ISE中的PLL时钟输入
在manaul mode中选择PLL PLL的输入时钟可以是全局时钟,也可以是普通IO引脚. 1.PLL的输入时钟是全局时钟的情况. pll_xx pll_xx ( .clkin ( clkin ), ...
- 网络爬虫-使用Python抓取网页数据
搬自大神boyXiong的干货! 闲来无事,看看了Python,发现这东西挺爽的,废话少说,就是干 准备搭建环境 因为是MAC电脑,所以自动安装了Python 2.7的版本 添加一个 库 Beauti ...