传送门

求两条最短路最多重叠的点数。
给一个无向图,再给两对起点终点,每一对起点终点之间都可能有多条最短的路,设s1t1的最短路是r1s2t2的最短路是r2,求r1r2最多能相互重叠多少个点。

这道题思想很巧妙,涉及了dp的思想。首先想明白一个问题,两条最短路最多的重叠部分必然是连续的,不可能有两段或更多段分散的重叠部分。为什么?反证法,若有的话,则某两段重叠部分之间的各自的分散部分一定可以都采用更小的那段分散部分。

建立一个数组cnt[][]记录全图的两点之间的最短路最多可以有多少条边,使用floyd算法,在g[i][k]+g[k][j] < g[i][j]g[i][k]+g[k][j] == g[i][j]两种情况下对cnt[i][j]进行计算。然而,还要对cnt[][]数组进行初始化,很直接的想法就是初始边的两点设为1,没有边的两点为0。但是,这里有一个坑!输入数据中实锤有自环! 自环意味着cnt[x][x]也被设为了1,但是这是不符合定义的,除非你这个自环的权值是非正数,但是根据题意,权值的实际意义是路的长度,都是正值。(如果是非正的话这题也就GG了,有可达的零环意味着可以在这个零环上走到死,使得重叠的点数无穷大,有可达的负环意味着你连最短路都求不出来)
说这么多就很简单,当a,b两点之间有边时,要在cnt[a][b] = cnt[b][a] = 1之前加上条件a != b

接下来提一下上述情况具体运行到哪里出了问题。
答案:当k==i或者k==j时,在floyd里的cnt[i][j] < cnt[i][k] + cnt[k][j]这个条件下引发了错误判断,继而计算了错误值。(想一想我在这个里面提过的三个情况)
证据:把输入边时的a!=b条件去掉,在floyd的此处加上条件&&(k!=i)&&(k!=j),也AC了。

最后,枚举每两个点,判断这两点之间的最短路能不能同时成为s1,t1s2,t2的最短路的一部分,这个判断的写法很巧妙,和cnt[][]没关系。若可以的话我们再拿这两点cnt[][]的值更新ans。(虽然这两点之间可能有多条最短路,但是这些最短路都是首尾一致的,可以随意替换,于是我们都拿cnt[][]最大的那个当作子路)

(4月9日更新:其实这个题只要在floyd里面让i,j,k各不相等就行了)


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
using namespace std;const int INF = 1e9;
const int MAXN = 301;
int N, M;int g[MAXN][MAXN];
int cnt[MAXN][MAXN];          // 两点的所有最短路上最多有几条边
int ans;void init()
{for (int i = 1; i <= N; i++){for (int j = i; j <= N; j++){if (i == j) g[i][j] = 0;else g[i][j] = g[j][i] = INF;}}memset(cnt, 0, sizeof cnt);ans = -1;
}int main()
{int a, b, c, d;for (; ~scanf("%d%d", &N, &M);){if (!N && !M) break;init();for (int i = 0; i < M; i++){scanf("%d%d%d", &a, &b, &c);g[a][b] = g[b][a] = min(g[a][b], c);if (a != b)                            // 如果来 X X Y 的数据怎么办? (自环)(Y肯定大于0)cnt[a][b] = cnt[b][a] = 1;         // 必须始终让cnt[x][x]=0,无论有没有自环,因为永远都不能走这个自环!                                      }scanf("%d%d%d%d", &a, &b, &c, &d);for (int k = 1; k <= N; k++){for (int i = 1; i <= N; i++){for (int j = 1; j <= N; j++){if (g[i][k] != INF && g[k][j] != INF && g[i][k] + g[k][j] < g[i][j]){g[i][j] = g[i][k] + g[k][j];cnt[i][j] = cnt[i][k] + cnt[k][j];}else if (g[i][k] + g[k][j] == g[i][j] && cnt[i][j] < cnt[i][k] + cnt[k][j]){cnt[i][j] = cnt[i][k] + cnt[k][j];}}}}for (int i = 1; i <= N; i++){for (int j = 1; j <= N; j++){if (cnt[i][j] > ans){if (g[a][b] == g[a][i] + g[i][j] + g[j][b] && g[c][d] == g[c][i] + g[i][j] + g[j][d]){                               // 表示i,j的最短路至少可以是a,b其中一条最短路的子路ans = cnt[i][j];}}}}printf("%d\n", ans + 1);     // 可以证明两条最短路的重叠部分一定是连续的,所以再加1等于重叠的点数}return 0;
}

转载于:https://www.cnblogs.com/CrossingOver/p/10704843.html

HDU 2833 WuKong相关推荐

  1. hdu 2833(Floyd + dp)

    WuKong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem D ...

  2. 杭电OJ分类题目(4)-Graph

    原题出处:HDOJ Problem Index by Type,http://acm.hdu.edu.cn/typeclass.php 杭电OJ分类题目(4) HDU Graph Theory - U ...

  3. 【转载】图论 500题——主要为hdu/poj/zoj

    转自--http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并 ...

  4. 【HDOJ图论题集】【转】

    1 =============================以下是最小生成树+并查集====================================== 2 [HDU] 3 1213 How ...

  5. 一系列图论问题[转]

    =============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many ...

  6. kk_想要学习的知识

    2018/4/27 计算几何 一.简介 计算几何属于ACM算法中比较冷门的分类,在省赛中只在前几年考察过,这两年还没有考过,而且和高精度计算一样,遇到题目主要靠套模板,因此对题意的理解至关重要,而且往 ...

  7. 图论练习题(存起来练)

    =============================以下是最小生成树+并查集======================================  [HDU]  1213 How Man ...

  8. ACM比赛经验、刷题记录及模板库总结(更新中)

    前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...

  9. 最短路径问题经典题目汇总

    50道数据结构最短路径问题 HDU 1142 http://acm.hdu.edu.cn/showproblem.php?pid=1142 HDU 1217 http://acm.hdu.edu.cn ...

最新文章

  1. mysql之修改表引擎
  2. 浅谈数据分析的魅力和能力要求!
  3. Android ----中文Api 百度地图
  4. java sql in无效数字_java.sql.SQLSyntaxErrorException: ORA-01722: 无效数字
  5. flutter打包出的问题
  6. Hive复杂数据类型 struct
  7. Pytorch中变量在tensor与numpy之间转换,tensor在CPU和GPU之间转换
  8. Linux内核分析——第四周学习笔记
  9. CentOS安装网络驱动
  10. 移位运算符 java_java.移位运算符
  11. div+css画六边形
  12. 贝塞尔曲线(Bezier)之 QQ 消息拖拽动画效果
  13. mysql-5.7.16安装教程_mysql installer community 5.7.16安装详细教程
  14. JavaWeb开发基础:Cookies/Session学习
  15. 我对说话人识别/声纹识别的研究综述
  16. Umi部署pages多页面访问配置
  17. CSS Div 实现舞台灯光效果
  18. php curl抓去网页名单,PHP CURL抓取网页 simple_html_dom类
  19. 集成电路工艺基础介绍以及什么是Corner?
  20. 程序员的神逻辑,不扶墙就服你!

热门文章

  1. asp.net ajax中文乱码的解决?2010-01-19 12:06
  2. 如何用javascript获取文本框,下拉框,单选框的对应值或者将值赋给它们?雪原虎 发布于:2007-10-22 00:32
  3. 23种设计模式C++源码与UML实现--工厂模式
  4. java基础 -- 数据类型,基本程序结构
  5. 《网络安全——应用技术与工程实践》
  6. 在EA中画ER图和数据模型图
  7. main函数解析(一)——Linux-0.11 学习笔记(五)
  8. 汽车车牌识别系统(六)-- 项目中的各个文件解析
  9. A wizard’s guide to Adversarial Autoencoders: Part 2, Exploring latent space with Adversarial Autoen
  10. 红茶一杯话Binder(传输机制篇_中)