转载:http://www.csie.ntnu.edu.tw/~u91029/Path3.html

在一張無向圖上面,給定圖上一點,以最短路徑長度當作距離,找出離此點最遠的一點,這兩點之間的距離就叫做「偏心距」。

要計算一張無向圖的直徑與半徑是很簡單的,首先算好所有兩點之間最短路徑,然後按照定義來算就可以了。

先用floyd算法,再找最长的即可

  1. int d[10][10];  // adjacency matrix
  2. int ecc[10];    // 各點的偏心距
  3. void diameter_radius()
  4. {
  5. // Floyd-Warshall Algorithm
  6. for (int k=0; k<10; ++k)
  7. for (int i=0; i<10; ++i)
  8. for (int j=0; j<10; ++j)
  9. d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
  10. // 計算偏心距
  11. memset(ecc, 0x7f, sizeof(ecc));
  12. for (int i=0; i<10; ++i)
  13. for (int j=0; j<10; ++j)
  14. ecc[i] = min(ecc[i], d[i][j]);
  15. // 計算直徑和半徑
  16. int diameter = 0;
  17. int radius = 1e9;
  18. for (int i=0; i<10; ++i)
  19. {
  20. diameter = max(diameter, ecc[i]);
  21. radius   = min(radius  , ecc[i]);
  22. }
  23. /*
  24. // 直徑也可以這樣算
  25. for (int i=0; i<10; ++i)
  26. for (int j=0; j<10; ++j)
  27. diameter = max(diameter, d[i][j]);
  28. */
  29. }

树形图的最长路径(边无权重)

方法1:

一棵無根樹的「直徑」,就是相離最遠的兩個點的距離。

稍微修改一下計算高度的程式碼,就可以順便計算直徑。

樹的直徑,邊無權重(adjacency matrix)
  1. bool adj[9][9];
  2. int diameter = 0;
  3. int DFS(int x, int px)  // px是x的父親
  4. {
  5. int h1 = 0, h2 = 0; // 紀錄最高與次高的高度
  6. for (int y=0; y<9; ++y)
  7. if (adj[x][y] && y != px)//记录父亲节点,防止重复访问
  8. {
  9. int h = DFS(y, x) + 1;
  10. if (h > h1) h2 = h1, h1 = h;
  11. else if (h > h2) h2 = h;
  12. }
  13. diameter = max(diameter, h1 + h2);
  14. return h1;
  15. }
  16. void tree_diameter()
  17. {
  18. diameter = 0;   // 初始化
  19. int root = 0;   // 隨便選一個樹根
  20. DFS(root, root);
  21. cout << "樹的直徑是" << diameter;
  22. }

一棵樹的各種直徑一定會相交在同一點(同一群點)。

1.
反證法。
現在有兩條分開的直徑,
可是一棵樹上各點都得連通,
所以這兩條分開的直徑,中間一定有某處互相連接,
一旦連接起來,勢必變成更長的直徑,矛盾。
故所有直徑必相交。2.
反證法。
現在已有兩條直徑相交在某一點,
如果另外一條直徑與這兩條直徑相交在另一點,
勢必變成更長的直徑,矛盾。
故所有直徑必相交在同一點(同一群點)。

方法二:

在一个迷宫中找距离最长的两个点。迷宫可以看作是一个无根树,因此,这个问题等价与在一个树形图中找最远的两个节点,也叫做这个图的直径。

迷宫、树形图有个很好的特点:任意两个节点之间的距离就是这两点之间的最短路径、也是两个节点的最长路径,也可以说任意两个节点之间的距离一定。基于这个想法,可以很快想到:穷举每个点对,计算其距离,取最大值,即可。这个计算量比较大,思想上可行,实践起来,时间代价有点不靠谱。查了下,已经有好的解决方案了:

1 取任意节点作为起点,找出到该点最远的点,记为A;

2 以点A为起点,找出到该点最远的点,记为B;

AB之间的距离,就是图中距离最远的两个点的距离(这样的点对可能有多个,但最大距离值只有一个)。

因此,两次dfs即可搞定。也可以用bfs

代码如下:

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

int m,n;

int f[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};

char map[1002][1002];

bool flag[1002][1002];

int max,step,maxM,maxN;

int si,sj;

void dfs(int i,int j)

{

int ii,a,b;

for(ii=0;ii<4;ii++)

{

a = i+ f[ii][0];

b = j+ f[ii][1];

if(a>=0 && a<m && b>=0 && b<n && map[a][b]=='.' && flag[a][b])

{

step++;

flag[a][b] = false;

if(max < step)

{

max = step;

maxM = a;

maxN = b;

}

dfs(a,b);

flag[a][b] = true;

step--;

}

}

}

int main()

{

int t,i,j;

scanf("%d",&t);

while(t--)

{

scanf("%d%d",&n,&m);

si = -1;

for(i=0;i<m;i++)

{

scanf("%s",map[i]);

if(si==-1)

for(j=0;j<n;j++)

if(map[i][j]=='.')

{

si = i;

sj = j;

break;;

}

}

memset(flag, true, sizeof(flag));

flag[si][sj] = false;

max = 0;

step = 0;

dfs(si,sj);

memset(flag, true, sizeof(flag));

flag[maxM][maxN] = false;

max = 0;

step = 0;

dfs(maxM, maxN);

printf("Maximum rope length is %d.\n",max);

}

system("pause");

return 0;

}

如果边有权重的话,感觉着两个算法也能正常工作

无向图的直径以及树的直径相关推荐

  1. 树的直径1——树的直径

    树的直径1--树的直径 目录 题目:树的直径1 题面 题目描述 输入描述 输出描述 样例输入 样例输出 数据范围 代码及思路 解题思路 AC代码 知识点:树的直径 定义 性质 查找"树的直径 ...

  2. 【洛谷 P3304】[SDOI2013]直径(树的直径)

    题目链接 题意,求一棵树被所有直径经过的边的条数. 这题是我们8.25KS图论的最后一题,当时我果断打了暴力求所有直径然后树上差分统计的方法,好像有点小问题,boom0了. 考完改这题,改了好久,各种 ...

  3. 0x63.图论 - 树的直径与最近公共祖先

    目录 一.树的直径(Diameter) 1.树形DP求树的直径 2.两次BFS/DFS求树的直径 1.POJ 1985.Cow Marathon(DFS求树的直径模板题) 2.AcWing 350. ...

  4. HDU - 4612 Warm up(边双缩点+树的直径)

    题目链接:点击查看 题目大意:给出一个由n个点和m条边构成的无向图,现在允许加一条边,使得整张图中桥的数量最少,求最少的桥的数量 题目分析:因为是要求桥,所以直接用tarjan边双缩点,将原图转换成一 ...

  5. 树的直径,树的最长路dp思想

    dp一直弱死了,树型dp很多基本的题都不会,最近在刷树型dp的题,把关于树的最长路的思想总结一下: 树的直径:树中距离最远的两点间的距离. 下面说几道题: hdu 2196:对于树上(双向边)的每一个 ...

  6. 【POJ - 3310】Caterpillar(并查集判树+树的直径求树脊椎(bfs记录路径)+dfs判支链)

    题干: An undirected graph is called a caterpillar if it is connected, has no cycles, and there is a pa ...

  7. 树形结构 —— 树与二叉树 —— 树的直径

    [定义] 给定一棵树,树中的每条边都有一个权值. 树中两点的距离:连接两点的路径边权之和 树的直径:树中最远的两个节点之间的距离 树的最长链:连接树中最远的两个结点的路径 [实现] 树的直径通常有两种 ...

  8. 【树上算法】树的直径

    树的直径 一.什么是树的直径 直径往往和圆有关系.数学中,圆的直径是圆内最长的一条线段.那么在树中,树的直径就是树中最长的一段距离. 二.计算树的直径的思路 命题: ①在树上任取一个点x,找到距离x最 ...

  9. Acwing1072 树的最长路径(树的直径)树形Dp 记忆化搜索

    题目描述 原题链接: https://www.acwing.com/problem/content/1074/ 思路 以下针对树的边权都一样的情况. 推荐使用BFS, 比赛的时候栈空间只有1MB,DF ...

最新文章

  1. yum 安装指定版本php,怎样通过yum安装指定版本的php
  2. 消费者版 Vive Trackers 正式发布,只会与 Steam 1.0 基站适配
  3. 2019 6月编程语言_六月开始提供435项免费在线编程和计算机科学课程
  4. mount 挂载光盘
  5. 品牌不可不知的YouTube的影片行销策略
  6. mysql alidata_linux下安装mysql | 学步园
  7. Python爬虫项目--爱拍视频批量下载
  8. Java项目——博客系统(毕业设计)
  9. 智能一代云平台(六):移动开发之Ionic研究
  10. 再见,Java 8!Java 17 竟然是史上最快的 JDK。。
  11. Beyond Compare怎么查看合并文本后相同内容
  12. 挑选32 2K显示器
  13. SVN客户端安装教程
  14. 记一次CAN报文过滤器组调试过程
  15. mysql dcn_Tdsql DCN同步技术原理介绍
  16. 聊聊另外一个Druid(很全)
  17. 中国版自动驾驶分级出炉!没有自动驾驶明星公司参与制定
  18. Activiti 学习笔记七:连线(SequenceFlow)
  19. vue3使用screenfull实现全屏
  20. POJ2325 Persistent Numbers

热门文章

  1. 为了OFFER,花了几个小时,刷下Leetcode链表算法题
  2. 北京内推 | 美团到店广告平台招聘广告算法专家(社招,L7-L8)
  3. Huggingface BERT源码详解:应用模型与训练优化
  4. 如何构造天然满足某些约束的神经网络?
  5. 第四届AutoDL挑战赛——AutoSpeech2019正式开赛
  6. php基础标签大全,HTML基础之HTML常用标签
  7. 中的挂起是什么意思_书房装饰挂什么画好 书法字画给你想要的诗意生活
  8. JVM 核心技术 调优分析与面试经验
  9. linux 进程死循环,Linux下如何处理一次用户态进程死循环问题
  10. atmega8a如何烧写程序_如何让树莓派4上固件的debug日志输出到串口?