【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 ...
随机推荐
- p76泛函 有限维空间真子空间不可能在全空间稠密
连续函数 然后多项式函数是稠密的 多项式子空间是无穷维的 多项式空间就是在全体连续函数的线性空间中稠密 有限维子空间是闭的 多项式空间也不是有限维 2的地方说 有限维真子空间必不稠密 那是对的啊 有 ...
- 使用PHPExcel导出数据库表结构及内容
导出表结构: mysql> desc user ; +----------+--------------+------+-----+---------------------+--------- ...
- 解决Window安全中心对Kitematic-0.17.3-Ubuntu.zip提示病毒,但无法删除的问题。
Trojan:JS/Tisifi.B 类型:特洛伊木马 containerfile: C:\Users\Administrator\Desktop\Kitematic-0.17.3-Ubuntu.zi ...
- php获取URL扩展名
一切拿代码来说话: 举例:'http://www.sina.com.cn/abc/de/fg.php?id=1': $url = 'http://www.sina.com.cn/abc/de/fg.p ...
- Day 5-7 exec 和元类的创建.
exec方法 元类 exec(str_command,globals,locals)参数1:字符串形式的命令参数2:全局作用域(字典形式). 如果不指定,默认globals参数3:局部作用(字典形式) ...
- 虚拟机的ip地址为什么会发生变化
因为虚拟机在NAT模式下由Vmware8虚拟网卡提供虚拟机的IP分配,网桥模式下由Vmware1来提供IP分配.它们都相当于 一个小型的DHCP服务器,除非改动虚拟机的网络连接方式,或动了虚拟网卡服务 ...
- AI算法第一天【概述与数学初步】
1. 机器学习的定义: 机器从数据中学习出规律和模式,以应用在新数据上作出预测的任务 2.学习现象: (1)语言文字的认知识别 (2)图像,场景,物体的认知和识别 (3)规则:下雨天要带雨伞 (4)复 ...
- mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱
mybatis逆向工程,实现join多表查询,避免多表相同字段名的陷阱 前言:使用 mybatis generator 生成表格对应的pojo.dao.mapper,以及对应的example的 ...
- 怎样利用ADO中的adoquery进行缓存更新?????(100分)
我用BDE时,用query与updatesql相结合进行缓存更新,但是在ADO中没有updatesql,只有用adoquery,在DBGRID中,用CANCELUPADTE,只能取消一条记录,烦恼不已 ...
- string.Format出现异常:输入字符串的格式不正确 Exception during StringFormat
错误信息:Exception during StringFormat:输入字符串的格式不正确 “System.FormatException”类型的未经处理的异常在 mscorlib.dll 中发生 ...