【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】游行(网络流)的更多相关文章

  1. 【BZOJ3691】游行 费用流

    [BZOJ3691]游行 Description 每年春季,在某岛屿上都会举行游行活动.在这个岛屿上有N个城市,M条连接着城市的有向道路.你要安排英雄们的巡游.英雄从城市si出发,经过若干个城市,到城 ...

  2. 【BZOJ3691】游行 最小可相交路径覆盖转化

    因为C是不断变化的而且C是和点权相关和边权无关 所以我们可以MCMF但是MCMF的时候不能与C相关 再分析问题 我们可以认为每条路径S->T只覆盖T这个终点 因为题目中说了如果Si != Ti ...

  3. plain framework 1 网络流 缓存数据详解

    网络流是什么?为什么网络流中需要存在缓存数据?为什么PF中要采用缓存网络数据的机制?带着这几个疑问,让我们好好详细的了解一下在网络数据交互中我们容易忽视以及薄弱的一块.该部分为PF现有的网络流模型,但 ...

  4. 网络流模板 NetworkFlow

    身边的小伙伴们都在愉快地刷网络流,我也来写一发模板好了. Network Flow - Maximum Flow Time Limit : 1 sec, Memory Limit : 65536 KB ...

  5. COGS732. [网络流24题] 试题库

    «问题描述:假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法.«编程任务: ...

  6. ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)

    //有流量上下界的网络流 //Time:47Ms Memory:1788K #include<iostream> #include<cstring> #include<c ...

  7. BZOJ 3144 [Hnoi2013]切糕 ——网络流

    [题目分析] 网络流好题! 从割的方面来考虑问题往往会得到简化. 当割掉i,j,k时,必定附近的要割在k-D到k+D上. 所以只需要建两条inf的边来强制,如果割不掉强制范围内的时候,原来的边一定会换 ...

  8. bzoj3572又TM是网络流

    = =我承认我写网络流写疯了 = =我承认前面几篇博文都是扯淡,我写的是垃圾dinic(根本不叫dinic) = =我承认这道题我调了半天 = =我承认我这道题一开始是T的,后来换上真正的dinic才 ...

  9. hdu3549还是网络流

    最后一次训练模板(比较熟练了) 接下来训练网络流的建图 #include <cstdio> #define INF 2147483647 int n,m,ans,x,y,z,M,h,t,T ...

随机推荐

  1. Python“Non-ASCII character 'xe5' in file”报错问题

    今天在编译一个Python程序的时候,一直出现“Non-ASCII character 'xe5' in file”报错问题 SyntaxError: Non-ASCII character '\xe ...

  2. 【kindle笔记】之 《浪潮之巅》- 2018-1-

    <浪潮之巅> 这本书推荐自最爱的政治课老师. 政治课老师张巍老师.我会一直记得你的. 以这样的身份来到这个学校,他人的质疑,自己的忐忑,老板的不公.犹犹豫豫谨小慎微地前进. 第一次听到这样 ...

  3. IntelliJ IDEA/WebStrom破解及JDK配置

    title: IntelliJ IDEA/WebStrom破解及JDK配置 (一)破解 破解步骤 第一步:下载破解补丁 第二步:修改配置文件 第三步:重启IntelliJ IDEA/WebStrom填 ...

  4. Windows Docker 安装

    win7.win8 .win10等需要利用 docker toolbox 来安装,国内可以使用阿里云的镜像来下载,下载地址:http://mirrors.aliyun.com/docker-toolb ...

  5. Laravel5 创建自定义门面(Facade)

    门面为应用服务容器中的绑定类提供了一个“静态”接口.Laravel 内置了很多门面,你可能在不知道的情况下正在使用它们.Laravel 的门面作为服务容器中底层类的“静态代理”,相比于传统静态方法,在 ...

  6. 【学亮IT手记】利用字节流复制图片

  7. Day 5-5 绑定方法与非绑定方法

    绑定方法与非绑定方法: 在类内部定义的绑定方法,分两大类: classmehtod是给类用的,即绑定到类,类在使用时会将类本身当做参数传给类方法的第一个参数(即便是对象来调用也会将类当作第一个参数传入 ...

  8. Sqoop 使用详解(内含对官方文档的解析)

    Sqoop 是 Cloudera 公司创造的一个数据同步工具,现在已经完全开源了. 目前已经是 hadoop 生态环境中数据迁移的首选,另外还有 ali 开发的 DataX 属于同类型工具,由于社区的 ...

  9. 【转】说说MySQL中的Redo log Undo log都在干啥

    阅读目录(Content) 1 undo 1.1 undo是啥 1.2 undo参数 1.3 undo空间管理 2 redo 2.1 redo是啥 2.2 redo 参数 2.3 redo 空间管理 ...

  10. BugFree 安装

    BugFree基于PHP和MySQL开发,是免费且开发源代码的缺陷管理系统.服务器端在Linux和Windows平台上都可以运行:客户端无需安装任何软件,通过IE,FireFox等浏览器就可以自由使用 ...