Description

小$W$非常喜欢社会主义,这天他开始研究它的优越性。
他发现它们国家十分乐于修建特色的社会主义道路。具体的说,$Z$国有$n$座城市,由$m$条有向边连接,城市从$1$编号。
特色的地方在于,时不时会有一些$LD$下来在城市间视察,视察时他会从城市$b_i$开始,最终到$e_i$结束。每次视察都会走过一些路,这些路自然会被$LD$所注意。
更具体地, $LD$会重修自己走过的路。每条边重修需要的费用也不相同。
而如果视察结束后, $LD$不在一开始自己所在的城市$b_i$,则会要新建一条$VIP$道路送他回家,也就是只有他自己能通过的道路。这需要花费固定的费用$C$,这条道路走过后便会拆毁。
若某个城市没有被$LD$经过,则这个城市的下级$LD$会被勒令整改,也要花费$C$的费用。
现在有$k$年,每年有若干个$LD$下来视察(可能$0$个),每年的固定费用$C$不同。小$W$想知道对于每一年怎样安排他们的视察人数和视察路线,能使得总花费最小。注意,领导至少要视察一条边。
注意,若一条道路被同一个人多次经过,则每次都会重修这条路。多个人多次经过也是一样。没有被$LD$经过的城市,更具体的说是没有被任何$LD$经过。

Input

第一行三个整数$n,m,k$。

接下来$m$行每行三个整数$s_i,t_i,v_i$,表示$s_i$和$t_i$间的有向边,重修需要花费$v_i$的代价。接下来$k$行每行一个整数,表示这一年的固定费用$C$。

Output

输出$k$行,每行一个最小花费。

Sample Input

6 5 3 6

1 3 2

2 3 2

3 4 2

4 5 2

4 6 2

1

5

10

Sample Output

6

21

32

HINT

$2\;\leq\;n\;\leq\;250,1\;\leq\;m\;\leq\;30000,1\;\leq\;k\;\leq\;10000,s_i\not=t_i,1\;\leq\;v_i,C\;\leq\;10000$,一对城市间可能有多条单向路,图中无自环。

Solution

先求出原图的最短路建一张完全图,任意两点间的边权为原图中两点的最短路长度.

可以发现,每个点只会被最优路径经过一次.

由于一个点只被经过一次,且要找出一些路径使得它们的和最小,这非常想最小路径覆盖的模型,拆点建边.

接着做最小费用最大流,若流了$k$路径,则我们需支付$(n-k)C$.

证明:若这$k$路径首尾相连成一个环,则需对剩下$n-k$个城市支付$C$;若不是环,则这$k$路径经过$k+1$个点,需对剩下$n-k-1$个城市支付$C$,以及为$LD$修路回去的$C$.

接下来要决定流几条路径.显然,做费用流时,每次得到的路径的费用是单调不降的,也就是可以在做费用流时判断:若当前的费用$>C$,则停止费用流,剩下的城市用$C$补。

由于有多组$C$,所以考虑提前将所有$n$次流后所得到的费用用前缀和存下来,每次二分出需要流的路径条数.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 505
#define M 125505
#define INF 1000000000
using namespace std;
struct graph{
int nxt,to,f,w;
}e[M];
struct edge{
int s,t,w;
}a[M];
struct tag{
int e,v;
}pre[N];
int d[N][N],g[N],f[N],sum[N],dis[N],c,n,m,s,t,ti,cnt=1;
bool inq[N];queue<int> q;
inline int read(){
int ret=0;char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c)){
ret=(ret<<1)+(ret<<3)+c-'0';
c=getchar();
}
return ret;
}
inline void addedge(int x,int y,int f,int w){
e[++cnt].nxt=g[x];g[x]=cnt;
e[cnt].to=y;e[cnt].f=f;e[cnt].w=w;
}
inline void adde(int x,int y,int f,int w){
addedge(x,y,f,w);addedge(y,x,0,-w);
}
inline bool spfa(int u){
for(int i=1;i<=t;++i){
dis[i]=INF;inq[i]=false;
}
dis[u]=0;q.push(u);inq[u]=true;
while(!q.empty()){
u=q.front();q.pop();inq[u]=false;
for(int i=g[u];i;i=e[i].nxt)
if(e[i].f>0&&dis[u]+e[i].w<dis[e[i].to]){
dis[e[i].to]=dis[u]+e[i].w;
pre[e[i].to].e=i;pre[e[i].to].v=u;
if(!inq[e[i].to]){
q.push(e[i].to);inq[e[i].to]=true;
}
}
}
return dis[t]<INF;
}
inline int mf(int f){
int ret=0,d;
while(f){
if(!spfa(s)) return -1;
d=f;
for(int i=t;i!=s;i=pre[i].v)
d=min(d,e[pre[i].e].f);
ret+=d*dis[t];f-=d;
for(int i=t;i!=s;i=pre[i].v){
e[pre[i].e].f-=d;
e[pre[i].e^1].f+=d;
}
}
return ret;
}
inline void Aireen(){
n=read();m=read();ti=read();
for(int i=1;i<n;++i)
for(int j=i+1;j<=n;++j)
d[i][j]=d[j][i]=INF;
for(int i=1,j,k,w;i<=m;++i){
j=read();k=read();w=read();
d[j][k]=min(d[j][k],w);
}
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
t=n+1<<1;s=t-1;
for(int i=1;i<=n;++i){
adde(s,i,1,0);
adde(i+n,i,1,0);
adde(i+n,t,1,0);
}
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(i!=j&&d[i][j]<INF)
adde(i,j+n,1,d[i][j]);
for(m=1;m<=n;++m){
f[m]=mf(1);
if(f[m]<0) break;
sum[m]=sum[m-1]+f[m];
}
--m;
int l,r,mid;
while(ti--){
c=read();
l=0;r=m;
while(l<r){
mid=l+r+1>>1;
if(f[mid]<=c) l=mid;
else r=mid-1;
}
printf("%d\n",sum[l]+c*(n-l));
}
}
int main(){
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
Aireen();
fclose(stdin);
fclose(stdout);
return 0;
}

[日常训练]Z国特色社会路的更多相关文章

  1. 「日常训练」ZgukistringZ(Codeforces Round #307 Div. 2 B)

    题意与分析(CodeForces 551B) 这他妈哪里是日常训练,这是日常弟中弟. 题意是这样的,给出一个字符串A,再给出两个字符串B,C,求A中任意量字符交换后(不限制次数)能够得到的使B,C作为 ...

  2. [日常训练]school

    Description 众所周知,家离学校很远.于是,每天算准了时间出发,以保证能在上课铃响前 秒到达学校. 不幸的是,市最近正在修路.这就导致有些路可能无法通行,因而可能导致迟到. 不打算改变他的出 ...

  3. 集训队日常训练20181124 DIV2

    急急忙忙要出去比赛就拉了一场有点sb的题目 5202: 网络寻路  时间限制(普通/Java):1000MS/3000MS     内存限制:65536KByte总提交: 15            ...

  4. [日常训练]string

    Description 给定一个长度为$n$的字符串,串中的字符保证是前$k$个小写字母.你可以在字符串后再添加$m$个字符,使得新字符串所包含的不同的子序列数量尽量多.当然,前提是只能添加前$k$个 ...

  5. [日常训练]常州集训day5

    T1 Description 小$W$和小$M$一起玩拼图游戏啦~ 小$M$给小$M$一张$N$个点的图,有$M$条可选无向边,每条边有一个甜蜜值,小$W$要选$K$条边,使得任意两点间最多有一条路径 ...

  6. [日常训练]常州集训day2

    T1 Description 给定$N$个点,问这$N$个点能构成的三角形个数. Input 第一行一个整数$N$,代表点数. 接下来$N$行,每行两个非负整数$X,Y$,表示一个点的坐标. Outp ...

  7. 日常训练 dfs 之 拓扑排序

    今天被拓扑排序给折磨了一天,主要就是我的一个代码有点小bug,真难找... 先来看看我今天写的题目吧! C. Fox And Names Fox Ciel is going to publish a ...

  8. 「日常训练」 Fire!(UVA-11624)

    与其说是训练不如说是重温.重新写了Java版本的代码. import java.util.*; import java.math.*; import java.io.BufferedInputStre ...

  9. 「日常训练」Equation(HDU-5937)

    题意与分析 时隔一个月之后来补题.说写掉的肯定会写掉. 题意是这样的:给1~9这些数字,每个数字有\(X_i\)个,问总共能凑成多少个不同的等式\(A+B=C\)(\(A,B,C\)均为1位,\(1+ ...

随机推荐

  1. mysql 数据库表名大小写问题

    lower_case_table_names=1 原来Linux下的MySQL默认是区分表名大小写的,通过如下设置,可以让MySQL不区分表名大小写:1.用root登录,修改 /usr/my.cnf: ...

  2. Centos7 下安装mysql数据库

    centos7系统,安装mysql发现已经默认的是mariadb. 只能安装mariadb,mariadb是mysql一个分支,对mysql完全支持 1 安装 yum -y install maria ...

  3. 第08章—整合Spring Data JPA

    spring boot 系列学习记录:http://www.cnblogs.com/jinxiaohang/p/8111057.html 码云源码地址:https://gitee.com/jinxia ...

  4. SOE不能进入断点调试

    一.前言 任何程序开发,如果不能进入断点调试,是非常的痛苦的. 如果有过SOE开发经验的人都知道,SOE开发过程中调试是非常麻烦的.任何在SOE开发模板中的修改都需要重新编译工程,重新生成.soe 文 ...

  5. Spring 的IOC容器之XML方式

    1. Spring 入门 1.1 概述 Spring 是一个分层的 JavaEE 轻量级开源框架; Spring 的核心是控制反转(IOC)和面向切面(AOP); 1.2 特点 方便解耦,简化开发; ...

  6. 0407-服务注册与发现-Eureka深入理解-元数据、高可用HA

    一.Eureka元数据 参看地址:https://cloud.spring.io/spring-cloud-static/Edgware.SR3/single/spring-cloud.html#_e ...

  7. Android studio 如何快速收起代码?

    windows下 ctrl+shift+(小键盘上的减号 -) mac下 commang+shift+减号,搞定

  8. springcloud Hystrix fallback无效

    在使用feign调用服务的时候防止雪崩效应,因此需要添加熔断器.(基于springboot2.0) 一.在控制器的方法上添加  fallbackMethod ,写一个方法返回,无须在配置文件中配置,因 ...

  9. 维多利亚的秘密 golang入坑系列

    原文在gitbook,字字原创,版权没有,转载随意. 在写本文的前一天,2017维密在上海开始了. 为了纪念屌丝界的盛世,特为本节起名维多利亚的秘密.现在的社会,要想出名只有抓眼球.所以写份技术文章, ...

  10. Config Static IP Address manually in Ubuntu

    The process of the configuration of static IP address in Ubuntu is as follows: ``` $ sudo vim /etc/n ...