因为C是不断变化的而且C是和点权相关和边权无关 所以我们可以MCMF但是MCMF的时候不能与C相关

再分析问题 我们可以认为每条路径S->T只覆盖T这个终点 因为题目中说了如果Si != Ti 要多付出 C的代价

假设我们走过的路径形成了一个环则刚好 边数=点数 覆盖完了

如果走过的路径不是一个环 则还有起点没有覆盖 此时我们可以把它当作没有途径的城市 给他补偿 同样为C

所以我们把原图拆成左边出点 右边入点 传递闭包后建图

这样每次MCMF增广的代价是不递减的 并且每增广一次多覆盖一个点 所以我们把每次增广的代价放到一个数组里面

每次询问我们二分C在数组里的位置,在C之前的点我们利用路径覆盖 在C及C之后的点我们用C去补偿它

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX 255
inline int read() {
int x = ;
bool t = false;
char ch = getchar();
while ((ch < '' || ch > '') && ch != '-')
ch = getchar();
if (ch == '-')
t = true, ch = getchar();
while (ch <= '' && ch >= '')
x = x * + ch - , ch = getchar();
return t ? -x : x;
}
int val[MAX], sum[MAX], tot;
namespace MCMF {
const int MAXM = , MAXN = ;
struct Line {
int v, next, w, fy;
} e[MAXM];
int h[MAXN], cnt = ;
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], , -fy
};
h[v] = cnt++;
}
int dis[MAXN], pe[MAXN], pv[MAXN], Cost, Flow;
bool vis[MAXN];
queue<int> Q;
int S = , T = MAXN - ;
bool SPFA() {
memset(dis, , sizeof(dis));
dis[S] = ;
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] ^ ].w += flow;
Flow += flow;
Cost += dis[T] * flow;
val[++tot] = dis[T] * flow;
sum[tot] = sum[tot - ] + val[tot];
return true;
}
}
using namespace MCMF;
int n, m, q, g[MAX][MAX];
int main() {
n = read();
m = read();
q = read();
memset(g, , sizeof(g));
for (int i = ; i <= n; ++i)
g[i][i] = ;
for (int i = , u, v; i <= m; ++i)
u = read(), v = read(), g[u][v] = min(read(), g[u][v]);
for (int k = ; k <= n; ++k)
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
for (int i = ; i <= n; ++i)
for (int j = ; j <= n; ++j)
if (i ^ j)
Add(i, j + n, , g[i][j]);
for (int i = ; i <= n; ++i)
Add(S, i, , ), Add(i + n, T, , );
while (SPFA());
while (q--) {
int C = read(), l = , r = tot, ret = ;
while (l <= r) {
int mid = (l + r) >> ;
if (val[mid] < C)
l = mid + , ret = mid;
else
r = mid - ;
}
printf("%d\n", sum[ret] + (n - ret)*C);
}
return ;
}

【BZOJ3691】游行 最小可相交路径覆盖转化的更多相关文章

  1. POJ 2594 Treasure Exploration 最小可相交路径覆盖

    最小路径覆盖 DAG的最小可相交路径覆盖: 算法:先用floyd求出原图的传递闭包,即如果a到b有路径,那么就加边a->b.然后就转化成了最小不相交路径覆盖问题. 这里解释一下floyd的作用如 ...

  2. POJ2594 Treasure Exploration[DAG的最小可相交路径覆盖]

    Treasure Exploration Time Limit: 6000MS   Memory Limit: 65536K Total Submissions: 8301   Accepted: 3 ...

  3. POJ 2594 Treasure Exploration(最小可相交路径覆盖)题解

    题意:有n个点,m条单向边,每个机器人能沿着单向边走,能重复经过一个点,问最少几个机器人走遍n个点 思路:原来以前学的都是不能相交的算法....可相交的做法是跑Floyd把能到达的都加上边,然后跑最小 ...

  4. FJUT3591 侦测到在途的聚变打击(最小不可相交路径覆盖)题解

    题意:给你n个点,点间m条路,给出在每条路要走的时间.现在有q个任务,要摧毁q个点,每次提供ci和ti表示在时间ti摧毁点ci(必须正好在时间ti才能摧毁),每个点可能需要多次摧毁(同一时间能在同一个 ...

  5. 有向无环图(DAG)的最小路径覆盖(转)

    DAG的最小路径覆盖 定义:在一个有向图中,找出最少的路径,使得这些路径经过了所有的点. 最小路径覆盖分为最小不相交路径覆盖和最小可相交路径覆盖. 最小不相交路径覆盖:每一条路径经过的顶点各不相同.如 ...

  6. 有向无环图(DAG)的最小路径覆盖

    DAG的最小路径覆盖 定义:在一个有向图中,找出最少的路径,使得这些路径经过了所有的点. 最小路径覆盖分为最小不相交路径覆盖和最小可相交路径覆盖. 最小不相交路径覆盖:每一条路径经过的顶点各不相同.如 ...

  7. HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...

  8. POJ 2594 (传递闭包 + 最小路径覆盖)

    题目链接: POJ 2594 题目大意:给你 1~N 个点, M 条有向边.问你最少需要多少个机器人,让它们走完所有节点,不同的机器人可以走过同样的一条路,图保证为 DAG. 很明显是 最小可相交路径 ...

  9. Air Raid POJ - 1422 【有向无环图(DAG)的最小路径覆盖【最小不相交路径覆盖】 模板题】

    Consider a town where all the streets are one-way and each street leads from one intersection to ano ...

随机推荐

  1. vue 服务器Linux部署

    1.打包vue项目 执行命令npm  run  build,然后会生成一个文件夹dist,里面的文件就是打包文件. 2.上传vue的打包文件,放在合适的文件夹下,例如/var/www 3.配置ngin ...

  2. VC.DNS解析(winsock)

    1.尝试了 gethostbyname(...) 和 Qt598中的qhostinfo::fromname(...),都可以解析出来IP,但是有一个问题:域名指向的IP改变了,这两种方式需要等较长时间 ...

  3. 热修复干货| AndFix热补丁动态修复框架使用教程

    本篇文章会与大家一起学习使用阿里的AndFix热修复框架,可以说AndFix是国内热修复技术的开山始祖,尽管现在阿里已经放弃了对这个项目的维护,但是后来很多的热修复技术都借鉴了这一框架的实现思路. 1 ...

  4. 将linux的root用户的家目录由/root切换为/home/root

    步骤1,先以root登录,然后创建目录/home/root步骤2,vi /etc/passwd里root用户的家目录为/home/root:步骤3,cp -rf /root/ /home/将原来的ro ...

  5. 关于 Visual Studio 的代码度量值

    查看方式:Visual Studio -> Analyze -> Calculate code metrics feature 代码度量(Code Metrics)是用来测量专业标准的软件 ...

  6. MySQL基础操作(一)

    MySQL操作 一.创建数据库 # utf CREATE DATABASE 数据库名称 DEFAULT CHARSET utf8 COLLATE utf8_general_ci; # gbk CREA ...

  7. QT 创建一个线程播放监控视频

    1.创建一个线程类(PlayVideoThread): PlayVideoThread.h头文件 #pragma once #include <QObject> #include &quo ...

  8. matplotlib实例笔记

    下面的图型是在一幅画布上建立的四个球员相关数据的极坐标图 关于这个图的代码如下: #_*_coding:utf-8_*_ import numpy as np import matplotlib.py ...

  9. Scala Map与Tuple

    创建Map // 创建一个不可变的Map val ages = Map("Leo" -> 30, "Jen" -> 25, "Jack&q ...

  10. CH08 QSPI启动并从EMMC运行APP

    8.1 概述 在前一节课,我们必须手动挂载TF卡到mnt,然后输入./a.out程序才能启动.而在嵌入式系统里面,我们很多时候需要实现开机启动程序.很多时候我们会把程序固化到FLASH,然后从EMMC ...