HDU6582链接

题意

在一张有向图中,有一个起点和一个终点,你需要删去部分路径,使得起点到终点的最短距离增加(并不要求需要使得距离变成最大值),且删除的路径长度最短。求删去的路径总长为多少

分析

一开始理解错题意了,以为是在保证路径变成最长的路径之后,求删去的路径和最小是多少。然后就自闭了很久,还WA了好几发。后来看到题目中是 longer 而不是 longest 。突然醒悟。直接最短路径 +网络流就行,中间重新建图。

大致的过程是先跑最短路径(我用了SPFA算法,因为当数据量较大时,图为稀疏图,所以用邻接表形式),然后求出起点到每一个点的距离(保存在数组 dist 中)。然后删掉所有的边,对满足下面等式的边进行重建(网络流的边,即同时需要搭建反向的边,只不过流量为0),然后跑网络流(我用了ISAP算法,仍然是邻接表)

dist[a]−dist[b]=edge[atob]dist[a] - dist[b] = edge[a to b]dist[a]−dist[b]=edge[atob]

atoba to batob 指代这条边起点为 aaa 终点为 bbb,且满足 edge[btoa]=−edge[atob]edge[b to a] = - edge[a to b]edge[btoa]=−edge[atob]

AC代码

#include <bits/stdc++.h>

using namespace std;

#define MAXN 20100
#define MAXM 20100 bool visited[MAXN]; //标记数组
long long dist[MAXN]; //源点到顶点i的最短距离
long long path[MAXN]; //记录最短路的路径
long long enqueue_num[MAXN]; //记录入队次数
long long vertex_num; //顶点数
long long edge_num; //边数
long long source; //源点 struct Edge
{
long long to, next, cap, flow;
} edge[MAXM];
long long head[MAXN];
long long tot;
long long gap[MAXN], dep[MAXN], cur[MAXN];
void init()
{
tot = 0;
memset(head, -1, sizeof(head));
} void addedge(long long u, long long v, long long w)
{
edge[tot].to = v;
edge[tot].cap = w;
edge[tot].next = head[u];
edge[tot].flow = 0;
head[u] = tot++;
} bool SPFA()
{
memset(visited, 0, sizeof(visited));
memset(enqueue_num, 0, sizeof(enqueue_num));
for (long long i = 0; i < vertex_num; i++)
{
dist[i] = __LONG_LONG_MAX__;
path[i] = source;
} queue<long long> Q;
Q.push(source);
dist[source] = 0;
visited[source] = true;
enqueue_num[source]++;
while (!Q.empty())
{
long long u = Q.front();
Q.pop();
visited[u] = 0;
for (long long curnode = head[u]; curnode != -1; curnode = edge[curnode].next)
{
if (dist[u] + edge[curnode].cap < dist[edge[curnode].to])
{
dist[edge[curnode].to] = dist[u] + edge[curnode].cap;
path[edge[curnode].to] = u;
if (!visited[edge[curnode].to])
{
Q.push(edge[curnode].to);
enqueue_num[edge[curnode].to]++;
if (enqueue_num[edge[curnode].to] >= vertex_num)
return false;
visited[edge[curnode].to] = 1;
}
}
}
}
return true;
}
long long Q[MAXN];
void BFS(long long start, long long end)
{
memset(dep, -1, sizeof(dep));
memset(gap, 0, sizeof(gap));
gap[0] = 1;
long long front = 0, rear = 0;
dep[end] = 0;
Q[rear++] = end;
while (front != rear)
{
long long u = Q[front++];
for (long long i = head[u]; i != -1; i = edge[i].next)
{
long long v = edge[i].to;
if (dep[v] != -1)
continue;
Q[rear++] = v;
dep[v] = dep[u] + 1;
gap[dep[v]]++;
}
}
} long long S[MAXN];
long long sap(long long start, long long end, long long N)
{
BFS(start, end);
memcpy(cur, head, sizeof(head));
long long top = 0;
long long u = start;
long long ans = 0;
while (dep[start] < N)
{
if (u == end)
{
long long Min = __LONG_LONG_MAX__;
long long inser;
for (long long i = 0; i < top; i++)
{
if (Min > edge[S[i]].cap - edge[S[i]].flow)
{
Min = edge[S[i]].cap - edge[S[i]].flow;
inser = i;
}
}
for (long long i = 0; i < top; i++)
{
edge[S[i]].flow += Min;
edge[S[i] ^ 1].flow -= Min;
}
ans += Min;
top = inser;
u = edge[S[top] ^ 1].to;
continue;
}
bool flag = false;
long long v;
for (long long i = cur[u]; i != -1; i = edge[i].next)
{
v = edge[i].to;
if (edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u])
{
flag = true;
cur[u] = i;
break;
}
}
if (flag)
{
S[top++] = cur[u];
u = v;
continue;
}
long long Min = N;
for (long long i = head[u]; i != -1; i = edge[i].next)
if (edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
{
Min = dep[edge[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if (!gap[dep[u]])
return ans;
dep[u] = Min + 1;
gap[dep[u]]++;
if (u != start)
u = edge[S[--top] ^ 1].to;
}
return ans;
}
long long n, m;
int a[MAXN], b[MAXN], c[MAXN]; void reISAP()
{
init();
for (int i = 0; i < m; i++)
{
if (c[i] == dist[b[i]] - dist[a[i]])
{
addedge(a[i], b[i], c[i]);
addedge(b[i], a[i], 0);
}
}
} int main()
{
#ifdef ACM_LOCAL
freopen("./in.txt", "r", stdin);
freopen("./out.txt", "w", stdout);
#endif
ios::sync_with_stdio(false);
long long t;
cin >> t;
while (t--)
{
cin >> n >> m;
source = 1;
vertex_num = n + 1;
init();
for (long long i = 0; i < m; i++)
{
cin >> a[i] >> b[i] >> c[i];
addedge(a[i], b[i], c[i]);
}
if (!SPFA())
{
cout << '0' << endl;
continue;
}
reISAP();
cout << sap(1, n, n) << endl;
}
return 0;
}

总结

理解了题意之后感觉就是一道板子题……

人尽皆知**题

【2019多校第一场补题 / HDU6582】2019多校第一场E题1005Path——最短路径+网络流的更多相关文章

  1. NOI.AC NOIP模拟赛 第一场 补记

    NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...

  2. NOI.AC NOIP模拟赛 第四场 补记

    NOI.AC NOIP模拟赛 第四场 补记 子图 题目大意: 一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图.删去第\(i\)条边需要\ ...

  3. 2019年第一天——使用Visual Studio 2019 Preview创建第一个ASP.Net Core3.0的App

    一.前言: 全文翻译自:https://www.talkingdotnet.com/creating-first-asp-net-core-3-0-app-visual-studio-2019/ Vi ...

  4. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  5. NOI.AC NOIP模拟赛 第二场 补记

    NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...

  6. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

  7. 剑指offer35题:第一个只出现一次的字符+剑指offer55题:字符流中第一个不重复的字符+剑指offer51题:数组中重复的数字

    在看剑指offer的时候,感觉这三个题目很像,都是用哈希表可以解决,所以把这三个题整理出来,以供复习. 剑指offer35题:第一个只出现一次的字符 题目描述:在字符串中找出第一个只出现一次的字符.如 ...

  8. Azure DevOps Server 2019 第一个补丁包(2019.0.1 RTW)

    在Azure DevOps Server 2019正式发布后的2周左右时间,微软快速发布了第一个补丁包Azure DevOps Server 2019.0.1 RTW.Azure DevOps Ser ...

  9. SQL SERVER 2005中如何获取日期(一个月的最后一日、上个月第一天、最后一天、一年的第一日等等)

    原文:[转]SQL SERVER 2005中如何获取日期(一个月的最后一日.上个月第一天.最后一天.一年的第一日等等) 在网上找到的一篇文章,相当不错哦O(∩_∩)O~ //C#本周第一天       ...

随机推荐

  1. Redis报错Can't save in background: fork: Cannot allocate memory及类似问题的处理方法

    问题的发现及解决过程: 1.Redis主从复制(一主一从)环境在客户端用命令查看主从状态 在slave上输入命令显示如下: 在master上输入命令显示如下: 从显示可以看出主从关系出现问题,然后查看 ...

  2. 码海拾遗:简述C++(一)

    C++是Bjarne Stroustrup博士于1982年,在C语言的基础上引入并扩充了面向对象的概念后发明的一种新的程序语言.就与C语言的渊源而言,C++可以说是C语言的超集,它兼容C的一切(可能是 ...

  3. Python 零基础入门

    Python 零基础入门 1.1 Python介绍 Python 是一门优雅且健壮的面向对象解释型计算机程序编程语言,具有面向对象.可升级.可扩展.可移植 语法简洁清晰易学.易读写.易维护.健壮性.通 ...

  4. Dream权限追踪系统<=2.0.1 重安装漏洞

    在./install/install.php中 if(file_exists('lock.txt')){ echo '系统已安装,请不要重复安装!如需安装,请删除install文件夹下的lock.tx ...

  5. Emacs key bindings for vim users

    Emacs key bindings for vim users | Scarletsky 盒子 盒子 博客 分类 标签 关于 RSS 搜索 文章目录 简介 Emacs 是一个文本编辑器,号称是伪装成 ...

  6. 在 LaTeX 中实现缩印效果

    https://liam.page/ 近日大概重拾了一点对 LaTeX 的兴趣,遇见这样一个问题:如何在 LaTeX 中实现缩印效果(即,将两页或更多页排版在一页纸上),并且实现水印效果的页码? 缩印 ...

  7. 对话|首席研究员童欣:从长远看,AR的应用范围远比VR广泛

    ​童欣博士现任微软亚洲研究院网络图形组首席研究员.1993年毕业于浙江大学计算机系,获工学学士学位:1996年获浙江大学计算机系硕士学位:1999年获清华大学计算机系博士学位,同年加入微软亚洲研究院. ...

  8. 联想拯救者y7000使用体验

    前言 我以前的电脑是在电商平台买的二手电脑,期间觉得软件的运行速度慢,又在网上买了一个128G的固态硬盘安装上.就从大一到大四上学期这么使用了三年半的时间.因为自己需要运行一些吃内存的软件,而我的这个 ...

  9. Newman+Jenkins实现接口自动化测试

    目录 一.是什么Newman 二.如何安装 三.如何使用 1.运行本地文件 2.运行在线文件 3.以node.js库运行 4.导出报告 四.命令行测试真实接口 1.导出collection文件 2.导 ...

  10. PostCSS的插件 -- 关于vue rem适配布局方案

    PostCSS的插件 作用:用于自动将像素单元生成rem单位 记以下三种 postcss-plugin-px2rem postcss-pxtorem postcss-px2rem 任选一种,最近大家推 ...