【BZOJ2324】[ZJOI2011]营救皮卡丘(网络流,费用流)

题面

BZOJ

洛谷

题解

如果考虑每个人走的路径,就会很麻烦。

转过来考虑每个人破坏的点集,这样子每个人可以得到一个上升的序列。

预处理\(dis[u][v]\)表示\(u\rightarrow v\)在不经过标号大于\(max\{u,v\}\)的点的情况下的最短路。

这个可以\(Floyd\)预处理。

不妨把\(0\)号点加入到每个人的序列开头,这样子一个假设一个人的序列是\(P\),那么他经过的所有边的和就是\(\sum_{i=2}^{|P|}dis[P_{i-1}][P_i]\)。

这样子就可以构建一个\(DAG\),然后要找出不超过\(k\)条路径来覆盖,对于两个点\(i,j,i<j\),从\(i\)到\(j\)的费用为\(dis[i][j]\)。

为了强制每个点都被访问过,把点拆成两个,因为是路径覆盖,所以每个点入度出度一进一出。

把每个点拆成入点和出点,出点作为\(i\),向其他点\(j\)的出点连边。

然后入点向\(T\)连边,表示必须有一个前驱,然后\(S\)向出点连边,表示必须有个后继。

然后\(S\)向\(0\)的出点连边,容量为\(K\),表示\(K\)条路径。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MAX 155
const int inf=150100;
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
namespace MCMF
{
const int MAXM=1000000,MAXN=1000;
struct Line{int v,next,w,fy;}e[MAXM];
int h[MAXN],cnt=2;
inline void Add(int u,int v,int w,int fy)
{
e[cnt]=(Line){v,h[u],w,fy};h[u]=cnt++;
e[cnt]=(Line){u,h[v],0,-fy};h[v]=cnt++;
}
int dis[MAXN],pe[MAXN],pv[MAXN],Cost,Flow;
bool vis[MAXN];queue<int> Que;
int S=MAXN-2,T=MAXN-1;
bool SPFA()
{
memset(dis,63,sizeof(dis));dis[S]=0;
Que.push(S);vis[S]=true;
while(!Que.empty())
{
int u=Que.front();Que.pop();
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(!e[i].w)continue;
if(dis[u]+e[i].fy<dis[v])
{
dis[v]=dis[u]+e[i].fy;pe[v]=i,pv[v]=u;
if(!vis[v])vis[v]=true,Que.push(v);
}
}
vis[u]=false;
}
if(dis[T]>=1e9)return false;
int flow=1e9;
for(int i=T;i!=S;i=pv[i])flow=min(flow,e[pe[i]].w);
for(int i=T;i!=S;i=pv[i])e[pe[i]].w-=flow,e[pe[i]^1].w+=flow;
Flow+=flow;Cost+=dis[T]*flow;
return true;
}
}
using namespace MCMF;
int n,m,K,g[MAX][MAX];
int main()
{
n=read();m=read();K=read();
memset(g,63,sizeof(g));for(int i=0;i<=n;++i)g[i][i]=0;
for(int i=1,u,v;i<=m;++i)u=read(),v=read(),g[u][v]=g[v][u]=min(g[u][v],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)g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
Add(S,0+n+1,K,0);
for(int i=1;i<=n;++i)Add(S,i+n+1,1,0),Add(i,T,1,0);
for(int i=0;i<=n;++i)
for(int j=i+1;j<=n;++j)
Add(i+n+1,j,1,g[i][j]);
while(SPFA());printf("%d\n",Cost);
return 0;
}

【BZOJ2324】[ZJOI2011]营救皮卡丘(网络流,费用流)的更多相关文章

  1. BZOJ2324 [ZJOI2011]营救皮卡丘 【费用流】

    题目 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双向道 ...

  2. BZOJ 2324: [ZJOI2011]营救皮卡丘( floyd + 费用流 )

    昨晚写的题...补发一下题解... 把1~N每个点拆成xi, yi 2个. 预处理i->j经过编号不超过max(i,j)的最短路(floyd) S->0(K, 0), S->xi(1 ...

  3. 【洛谷P4542】 [ZJOI2011]营救皮卡丘(费用流)

    洛谷 题意: 给出\(n\)个点,\(m\)条边,现在有\(k,k\leq 10\)个人从\(0\)号点出发前往\(n\)点. 规定若某个人想要到达\(x\)点,则\(1\)~\(x-1\)号点都有人 ...

  4. 【洛谷 P4542】 [ZJOI2011]营救皮卡丘(费用流)

    题目链接 用最多经过\(k\)条经过\(0\)的路径覆盖所有点. 定义\(ds[i][j]\)表示从\(i\)到\(j\)不经过大于\(max(i,j)\)的点的最短路,显然可以用弗洛伊德求. 然后每 ...

  5. bzoj2324 [ZJOI2011]营救皮卡丘 费用流

    [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2653  Solved: 1101[Submit][Status][D ...

  6. BZOJ2324: [ZJOI2011]营救皮卡丘

    2324: [ZJOI2011]营救皮卡丘 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1359  Solved: 522[Submit][Stat ...

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

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

  8. P4542-[ZJOI2011]营救皮卡丘【费用流,Floyd】

    正题 题目链接:https://www.luogu.com.cn/problem/P4542 题目大意 给出\(n+1\)个点\(m\)条边的无向图,\(k\)个人开始在\(0\)号点,一个人进入\( ...

  9. 【BZOJ2324】[ZJOI2011]营救皮卡丘 有上下界费用流

    [BZOJ2324][ZJOI2011]营救皮卡丘 Description 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的 ...

随机推荐

  1. oc之证书

    https://www.cnblogs.com/MrJalen/p/6813309.html iOS推送证书生成pem文件(详细步骤)   1.pem文件概述 pem文件是服务器向苹果服务器做推送时候 ...

  2. iOS上手指点击波纹效果的实现

    https://www.jianshu.com/p/35e6f53ca0fe 2016.10.19 22:00* 字数 135 阅读 2468评论 2喜欢 7 闲暇时间做了一个反馈手指点击屏幕的效果, ...

  3. python_format格式化输出、while else、逻辑运算符、编码初识

    1.格式化输出 .%d  %s  格式化输出:% 占位符,d 表示替换整型数,s表示要替换字符串. name = input('请输入名字:') age = input('请输入年龄:') sex = ...

  4. 福州大学软件工程1816 | W班 第4次作业(团队展示)成绩排名

    作业链接 评分细则 队员姓名与学号(标记组长),其中4-7人一组,特殊情况经老师允许后可以突破限制:(1分) 队名(体现项目内容,并要求有亮点与个性):(1分) 拟作的团队项目描述:一句话(中英文不限 ...

  5. 使用Dockerfile来构建镜像

    Dockerfile原理 创建Dockerfile Dockerfile实例 Dockerfile指令 注释 FROM MAINTAINER RUN ADD WORKDIR ENV USER COPY ...

  6. 【学习总结】C-翁恺老师-入门-第0周<程序设计与C>

    [学习总结]C-翁恺老师-入门-总 1-首先按视频说的下载编辑器 <DevC++> 并一路默认设置: 安装包下载链接 (我有vc6.0不过预感告诉我老师要用类似CS50里那种命令行编辑器? ...

  7. js判断是否是微信浏览器以及重定向

    async created () {//这个是判断是否是微信浏览器, let ua = navigator.userAgent.toLowerCase() if (ua.match(/MicroMes ...

  8. Bootstrap知识记录:表单和图片

    一.表单Bootstrap 提供了一些丰富的表单样式供开发者使用.1.基本格式//实现基本的表单样式<form><div class="form-group"&g ...

  9. IIS 使用 HTTP重定向 修改 默认主页

    1. 被自己坑死了 多了一个 正斜杠 浪费了好长好长的时间 2. 需求 直接输入ip地址 总是 弹出来 iis 的 welcome的界面 感觉很low 想要修改一下 曾经用过 reflesh 来修改过 ...

  10. day 7-6 多线程及开启方式

    一. 什么是线程 线程:顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程 ...