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. Inheritance Learning Note

    好几天没来学习了,昨晚把继承的又整理了一下.想把整理后的东西发到hexo博客上来,却发现命令行又失效了.前几天明明是好的,这几天又没有进行任何操作,网上搜了一下也没有招到合适的解决办法,无奈只能重装了 ...

  2. flask 中文乱码

    返回的json数据中包含中文,但前端显示乱码,添加了 app.config['JSON_AS_ASCII'] = False仍然没有解决, app.config['JSONIFY_MIMETYPE'] ...

  3. 量化投资学习笔记31——《Python机器学习应用》课程笔记05

    用分类算法进行上证指数涨跌预测. 根据今天以前的150个交易日的数据,预测今日股市涨跌. 交叉验证的思想:将数据集D划分为k个大小相似的互斥子集,每个子集都尽可能保持数据分布的一致性,即从D中通过分层 ...

  4. tp5.1 请求时间格式化

    当前时间:{$Request.time|date='Y-m-d H:i:s'} 注意database.php的配置!记录一下!

  5. 【Art】物理课题——虹吸

    前言(无关闲话):在此之前,课题小组讨论了三.四次,得有10个小时了总共,但是具体还是在普及常识,那就在这里深入地讲一下. 进入正题—— 这就是虹吸的基本模型,再看一下百度的官方说法: “虹吸(sip ...

  6. PyCharm使用技巧及常用快捷键

    Ctrl + Shift + F--------------------------------------------->>>>>>>高级查找 Ctrl + ...

  7. Pycharm IDE安装及注册激活笔记(1)

    一.Windows 下的安装及激活. 1.首先去Pycharm官网,或者直接输入网址:http://www.jetbrains.com/pycharm/download/#section=window ...

  8. VMware虚拟机从安装到激活再到创建虚拟机解决黑屏、卡、死机系列问题教程第二篇

    第二篇:在VMware中创建一个虚拟机(黑屏死机卡在最下面简单说一下你就懂了) 1.我们要打开我们已经安装好的VMware,然后点击创建新的虚拟机 2.然后选择自定义 3.下面这个默认,直接下一步 4 ...

  9. RabbitMQ 消息模式

    消息模式实例 视频教程:https://ke.qq.com/course/304104 编写代码前,最好先添加好用户并设置virtual hosts 一.简单模式 1.导入jar包 <depen ...

  10. vuex的使用心得

    今天的工作内容-----vuex的使用心得: 都知道,对于小型的项目来说不必使用vuex,但是对于需要把共享的变量全部存储在一个对象里面,然后把这个对象放在顶层组件中以供其他组件使用.其实vuex就是 ...