【BZOJ3691】游行(网络流)
【BZOJ3691】游行(网络流)
题面
BZOJ
然而权限题。
Description
每年春季,在某岛屿上都会举行游行活动。
在这个岛屿上有N个城市,M条连接着城市的有向道路。
你要安排英雄们的巡游。英雄从城市si出发,经过若干个城市,到城市ti结束,需要特别注意的是,每个英雄的巡游的si可以和ti相同,但是必须至少途径2个城市。
每次游行你的花费将由3部分构成:
1.每个英雄游行经过的距离之和,需要特别注意的是,假如一条边被途径了k次,那么它对答案的贡献是k*ci,ci表示这条边的边权。
2.如果一个英雄的巡游的si不等于ti,那么会额外增加C的费用。因为英雄要打的回到起点。
3.如果一个城市没有任何一个英雄途经,那么这个城市会很不高兴,需要C费用的补偿。
你有无数个的英雄。你要合理安排游行方案,使得费用最小。
由于每年,C值都是不一样的。所以你要回答Q个询问,每个询问都是,当C为当前输入数值的时候的答案。
Input
第一行正整数N,M,Q;
接下来的M行,每行ai,bi,ci,表示有一条从ai到bi,边权为ci的有向道路。保证不会有自环,但不保证没有重边。
接下来Q行,每行一个C,表示询问当每次费用为C时的最小答案。
Output
Q行,每行代表一个询问的答案。
Sample Input
6 5 3
1 3 2
2 3 2
3 4 2
4 5 2
4 6 2
1
5
10
Sample Output
6
21
32
题解
没想到我竟然放了题面
发现\(C\)是在不断变化的,所以考虑计算一个和\(C\)无关的东西,最后再把\(C\)的贡献考虑进来。
先把两个和\(C\)相关的限制给统一起来,我们认为一条路径只覆盖其终点,其起点不被覆盖,那么最终所有的未被覆盖的点产生\(C\)的贡献。
这样子看起来还是有点区别的,主要问题在于经过了一个环,然后回到了起点\(S\),再走出去确定了一个终点\(T\),这样子看起来覆盖了所有点,但是仍要付出一个\(C\)的代价。
实际上这样子没错,但是这样子不优,因为你可以只走环,然后把剩下的路径给拆开,这样子代价仍然是一个\(C\),但是少走了一条边的代价。
实际上我们做的是一个最小路径覆盖,这样就会得到比上述东西更优的一个解。
两点之间连边边权为两点之间的最短路,然后跑最短路径覆盖,这样子每次都会新增一个点进入覆盖,并且权值是单增的。
那么只需要对于每次询问二分权值从哪里开始大于\(C\),前面的路径覆盖,后面的直接用\(C\)即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long
#define MAX 255
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;
}
int val[MAX],sum[MAX],tot;
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> Q;
int S=0,T=MAXN-1;
bool SPFA()
{
memset(dis,63,sizeof(dis));dis[S]=0;
Q.push(S);vis[S]=true;
while(!Q.empty())
{
int u=Q.front();Q.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,Q.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;
val[++tot]=dis[T]*flow;sum[tot]=sum[tot-1]+val[tot];
return true;
}
}
using namespace MCMF;
int n,m,q,g[MAX][MAX];
int main()
{
n=read();m=read();q=read();
memset(g,63,sizeof(g));for(int i=1;i<=n;++i)g[i][i]=0;
for(int i=1,u,v;i<=m;++i)u=read(),v=read(),g[u][v]=min(read(),g[u][v]);
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(i^j)Add(i,j+n,1,g[i][j]);
for(int i=1;i<=n;++i)Add(S,i,1,0),Add(i+n,T,1,0);
while(SPFA());
while(q--)
{
int C=read(),l=1,r=tot,ret=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(val[mid]<C)l=mid+1,ret=mid;
else r=mid-1;
}
printf("%d\n",sum[ret]+(n-ret)*C);
}
return 0;
}
【BZOJ3691】游行(网络流)的更多相关文章
- 【BZOJ3691】游行 费用流
[BZOJ3691]游行 Description 每年春季,在某岛屿上都会举行游行活动.在这个岛屿上有N个城市,M条连接着城市的有向道路.你要安排英雄们的巡游.英雄从城市si出发,经过若干个城市,到城 ...
- 【BZOJ3691】游行 最小可相交路径覆盖转化
因为C是不断变化的而且C是和点权相关和边权无关 所以我们可以MCMF但是MCMF的时候不能与C相关 再分析问题 我们可以认为每条路径S->T只覆盖T这个终点 因为题目中说了如果Si != Ti ...
- plain framework 1 网络流 缓存数据详解
网络流是什么?为什么网络流中需要存在缓存数据?为什么PF中要采用缓存网络数据的机制?带着这几个疑问,让我们好好详细的了解一下在网络数据交互中我们容易忽视以及薄弱的一块.该部分为PF现有的网络流模型,但 ...
- 网络流模板 NetworkFlow
身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了. Network Flow - Maximum Flow Time Limit : 1 sec, Memory Limit : 65536 KB ...
- COGS732. [网络流24题] 试题库
«问题描述:假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法.«编程任务: ...
- ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)
//有流量上下界的网络流 //Time:47Ms Memory:1788K #include<iostream> #include<cstring> #include<c ...
- BZOJ 3144 [Hnoi2013]切糕 ——网络流
[题目分析] 网络流好题! 从割的方面来考虑问题往往会得到简化. 当割掉i,j,k时,必定附近的要割在k-D到k+D上. 所以只需要建两条inf的边来强制,如果割不掉强制范围内的时候,原来的边一定会换 ...
- bzoj3572又TM是网络流
= =我承认我写网络流写疯了 = =我承认前面几篇博文都是扯淡,我写的是垃圾dinic(根本不叫dinic) = =我承认这道题我调了半天 = =我承认我这道题一开始是T的,后来换上真正的dinic才 ...
- hdu3549还是网络流
最后一次训练模板(比较熟练了) 接下来训练网络流的建图 #include <cstdio> #define INF 2147483647 int n,m,ans,x,y,z,M,h,t,T ...
随机推荐
- haoop笔记
: //:什么是hadoop? hadoop是解决大数据问题的一整套技术方案 :hadoop的组成? 核心框架 分布式文件系统 分布式计算框架 分布式资源分配框架 hadoop对象存储 机器计算 :h ...
- Leaf——美团点评分布式ID生成系统 UUID & 类snowflake
Leaf——美团点评分布式ID生成系统 https://tech.meituan.com/MT_Leaf.html
- Non-Volatile Register 非易失性寄存器 调用约定对应寄存器使用
非易失性寄存器(Non-volatile register)是它的内容必须通过子程序调用被保存的一个寄存器.如果一个程序改变了一个非易失性寄存器的值,它必须保存在改变这个寄存器之前堆栈中保存旧的值和在 ...
- js-cookie和session
###1.cookie 含义: 存储在访问者的计算机中的变量,即存储在客户端 创建一个cookie /* getCookie方法判断document.cookie对象中是否存有cookie,若有则判断 ...
- 将form数据转换成json对象自定义插件实现思路
- 在 Ubuntu14.04 上搭建 Spark 2.3.1(latest version)
搭建最新的 Spark 2.3.1 . 首先需要下载最新版 jdk .目前 2.3.1 需要 8.0 及其以上 jdk 才可以允许. 所以如果你没有 8.0 jdk 安装好了之后会报错.不要尝试安装 ...
- 进阶开发——文档,缓存,ip限速
一.文档自动化管理 1.django rest framework提供了一个接口: 可以将代码中注释转换为文档中内容(list,create等),以及help_text等等,且会生成JavaScrip ...
- linux中一些特殊的中文文件不能删除问题
例: [root@iZ2zecl4i8oy1rvs00dqzeZ tmp]# ,),(,,' [root@iZ2zecl4i8oy1rvs00dqzeZ tmp]# echo "rm -rf ...
- MySQL系列:索引基本操作(4)
1. 索引简介 索引是一种特殊的数据库结构,可以用来快速查询数据中的特定记录. MySQL中索引包括:普通索引.唯一性索引.全文索引.单列索引.多列索引和空间索引等. 1.1 索引定义 索引由数据库表 ...
- Java HashMap的put操作(Java1.6)
https://www.cnblogs.com/skywang12345/p/3310835.html // 存储数据的Entry数组,长度是2的幂. // HashMap是采用拉链法实现的,每一个E ...