BZOJ.2324.[ZJOI2011]营救皮卡丘(费用流 Floyd)
首先预处理出\(dis[i][j]\),表示从\(i\)到\(j\)的最短路。可以用\(Floyd\)处理。
注意\(i,j\)是没有大小关系限制的(\(i>j\)的\(dis[i][j]\)也要求,虽然后面用不到),因为可以从\(i\)经过中间点\(k,\ i<k<j\),到达\(j\)。同时\(i\to j\)只能经过\(k<\max(i,j)\)的点,否则是走不了\(k\)的。
然后题意可以转化为用不超过\(k\)条路径覆盖所有点,最小化边权和。
拆点,建二分图。对于任意两点\(i,j,\ i<j\),只由\(i\)向\(j'\)连边,容量\(1\),费用为\(dis[i][j]\)。这样建有向边也符合从编号小的向大的走,也不会出现环。
从\(S\)向\(1,...,n\)连容量\(1\),费用\(0\)的边;\(1,...,n\)向\(T\)连容量\(1\),费用\(0\)的边。
\(S\)向\(0\)连容量\(k\),费用\(0\)的边;\(0\)向每个拆点后的点\(1',...,n'\)连容量\(1\),费用\(dis[0][i]\)的边。
然后跑最小费用最大流即可。
这样为什么可以满足\(k\)路径覆盖呢。。从\(0\)向\(i'\)流就表示新建一条\(0\to i'\to...\)的路径,不会超过\(k\)条。(如果是\(i\to j',\ i\neq0\),则表示在一条已有的路径中从\(i\)走到了\(j\))
同时图是\(DAG\),且会满流,所以一定合法。
终于遇到zkw比SPFA慢的题了/托腮。
SPFA:
//3072kb 220ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=305,M=(N*N/2+3*N)*2,INF=0x3f3f3f3f;
int S,T,Cost,Enum,H[N],nxt[M],fr[M],to[M],cap[M],cost[M],dis[N][N],pre[N];
bool vis[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int u,int v,int w,int c)
{
to[++Enum]=v, fr[Enum]=u, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w, cost[Enum]=c;
to[++Enum]=u, fr[Enum]=v, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0, cost[Enum]=-c;
}
bool SPFA()
{
static int dis[N];
static bool inq[N];
static std::queue<int> q;
memset(dis,0x3f,sizeof dis);
dis[S]=0, q.push(S);
while(!q.empty())
{
int x=q.front(); q.pop();
inq[x]=0;
for(int i=H[x],v; i; i=nxt[i])
if(cap[i] && dis[to[i]]>dis[x]+cost[i])
dis[v=to[i]]=dis[x]+cost[i], pre[v]=i, !inq[v]&&(q.push(v),inq[v]=1);
}
return dis[T]<INF;
}
inline void Augment()
{
for(int i=T; i!=S; i=fr[pre[i]])
--cap[pre[i]], ++cap[pre[i]^1], Cost+=cost[pre[i]];
}
int MCMF()
{
while(SPFA()) Augment();
return Cost;
}
int main()
{
const int n=read(),m=read(),K=read();
Enum=1, S=2*n+1, T=2*n+2;
memset(dis,0x3f,sizeof dis);
for(int i=0; i<=n; ++i) dis[i][i]=0;
for(int i=1,u,v; i<=m; ++i)
u=read(), v=read(), dis[u][v]=dis[v][u]=std::min(dis[v][u],read());
for(int k=0; k<=n; ++k)
for(int i=0; i<=n; ++i)
for(int j=0; j<=n; ++j)
if(k<i||k<j) dis[i][j]=std::min(dis[i][j],dis[i][k]+dis[k][j]);
AE(S,0,K,0);
for(int i=1; i<=n; ++i) AE(S,i,1,0), AE(i+n,T,1,0);
for(int i=0; i<n; ++i)
for(int j=i+1; j<=n; ++j)
AE(i,j+n,1,dis[i][j]);
printf("%d\n",MCMF());
return 0;
}
zkw:
//2704kb 280ms
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=305,M=(N*N/2+3*N)*2,INF=0x3f3f3f3f;
int S,T,Cost,Enum,cur[N],H[N],nxt[M],to[M],cap[M],cost[M],dis[N][N],f[N];
bool vis[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-48,c=gc());
return now;
}
inline void AE(int u,int v,int w,int c)
{
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w, cost[Enum]=c;
to[++Enum]=u, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0, cost[Enum]=-c;
}
bool SPFA()
{
static bool inq[N];
static std::queue<int> q;
memset(f,0x3f,T+1<<2);
f[S]=0, q.push(S);
while(!q.empty())
{
int x=q.front(); q.pop();
inq[x]=0;
for(int i=H[x],v; i; i=nxt[i])
if(cap[i] && f[to[i]]>f[x]+cost[i])
f[v=to[i]]=f[x]+cost[i], !inq[v]&&(q.push(v),inq[v]=1);
}
return f[T]<INF;
}
bool DFS(int x)
{
if(x==T) return 1;
vis[x]=1;
for(int &i=cur[x]; i; i=nxt[i])
if(cap[i] && !vis[to[i]] && f[to[i]]==f[x]+cost[i] && DFS(to[i]))//f not dis!
return --cap[i],++cap[i^1],Cost+=cost[i],1;
return 0;
}
int MCMF()
{
while(SPFA())
{
memset(vis,0,T+1), memcpy(cur,H,T+1<<2);
while(DFS(S));
}
return Cost;
}
int main()
{
const int n=read(),m=read(),K=read();
Enum=1, S=2*n+1, T=2*n+2;
memset(dis,0x3f,sizeof dis);
for(int i=0; i<=n; ++i) dis[i][i]=0;
for(int i=1,u,v; i<=m; ++i)
u=read(), v=read(), dis[u][v]=dis[v][u]=std::min(dis[v][u],read());
for(int k=0; k<=n; ++k)
for(int i=0; i<=n; ++i)
for(int j=0; j<=n; ++j)
if(k<i||k<j) dis[i][j]=std::min(dis[i][j],dis[i][k]+dis[k][j]);
AE(S,0,K,0);
for(int i=1; i<=n; ++i) AE(S,i,1,0), AE(i+n,T,1,0);
for(int i=0; i<n; ++i)
for(int j=i+1; j<=n; ++j)
AE(i,j+n,1,dis[i][j]);
printf("%d\n",MCMF());
return 0;
}
BZOJ.2324.[ZJOI2011]营救皮卡丘(费用流 Floyd)的更多相关文章
- bzoj 2324 ZJOI 营救皮卡丘 费用流
题的大概意思就是给定一个无向图,边有权值,现在你有k个人在0点,要求走到n点,且满足 1:人们可以分头行动,可以停在某一点不走了 2:当你走到x时,前x-1个点必须全部走过(不同的人走过也行,即分两路 ...
- 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 ...
- bzoj2324 [ZJOI2011]营救皮卡丘 费用流
[ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2653 Solved: 1101[Submit][Status][D ...
- BZOJ 2324: [ZJOI2011]营救皮卡丘(带上下限的最小费用最大流)
这道题么= =还是有些恶心的,第一次写带上下界的网络流,整个人都萌萌哒~~~ 首先先预处理得最短路后 直接用费用流做就行了。 第一次写,还是挺好写的= = CODE: #include<cstd ...
- bzoj 2324: [ZJOI2011]营救皮卡丘
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #inclu ...
- 【BZOJ 2324】[ZJOI2011]营救皮卡丘 费用流
本人实行诱骗拐卖(利用自然分层与实际意义),正解拼接补充(充分利用最大流限制(不浪费任何一个走出去的机会而不是不浪费任何一个已有的流)与问题转换) #include <cstdio> #i ...
- 【bzoj2324】[ZJOI2011]营救皮卡丘 最短路-Floyd+有上下界费用流
原文地址:http://www.cnblogs.com/GXZlegend/p/6832504.html 题目描述 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘 ...
- BZOJ2324: [ZJOI2011]营救皮卡丘
2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1359 Solved: 522[Submit][Stat ...
随机推荐
- node.js 框架express有关于router的运用
1.express 路由入门 const express = require('express'); let server = express(); server.listen(8087); //用户 ...
- Java享元模式
定义:提供了减少对象数量从而改善应用所需的对象结构的方式 运用共享技术有效支持大量细微度的对象 类型:结构型 应用场景:系统底层的开发啊,以便解决系统的性能问题 系统有大量的相似对象,需要缓存池的场景 ...
- 一个kubeadm.config文件--定义了token,扩展了默认端口,外部ETCD集群,自定义docker仓库,基于ipvs的kubeproxy
这个版本是基于kubeadm.k8s.io/v1alpha3的,如果到了beta1,可能还要变动呢. apiVersion: kubeadm.k8s.io/v1alpha3 kind: InitCon ...
- rabbitmq3.7.5 centos7 安装笔记
先安装各种依赖文件: yum -y install gcc glibc-devel make ncurses-devel openssl-devel xmlto perl wget vim 1. ra ...
- Elasticsearch集群
详细Elasticsearch安装: https://www.cnblogs.com/littlehb/p/8406378.html 安装之前需先优化内核: https://www.cnblogs.c ...
- 解决redis aof文件过大的问题
执行BGREWRITEAOF命令对redis的AOF进行重写 redis-cli BGREWRITEAOF 相关解释: Redis的AOF机制有点类似于Mysql binlog,是Redis的提供的一 ...
- 最大子数组(I, II, III,IV,V)和最大子数组乘积 (动态规划)
I 找一个连续最大子数组,sum加到nums[i], 如果前面子数组和<0则舍去,从头开始. class Solution { public: /** * @param nums: A list ...
- vue父组件传值给字组件
转自https://www.cnblogs.com/padding1015/p/7878710.html 父组件通过绑定 传入 数据的名称 值 子组件接收 type为数据类型
- Chino的数列
题解: 一道练代码能力的题目.. 首先很显然他是一道平衡树裸题 第5个操作是势能分析维护最大值最小值就可以了 另外设置虚点和noip2017队列那题一样(不过我只写过线段树) 具体细节: 1.内存池, ...
- [转]JAVA实现SFTP实例
http://www.cnblogs.com/chen1987lei/archive/2010/11/26/1888384.html 最近写的一个JAVA实现SFTP的实例: /** Created ...