树的直径 dfs bfs floyd

dfs的核心代码

void dfs(int s)
{
    for(int i = head[s]; i != -1; i = edge[i].nxt){
        int Eiv = edge[i].v;
        if(fa[s] == Eiv) continue; //不走回头路,也可以递归父亲结点省去fa数组空间
        fa[Eiv] = s;
        dis[Eiv] = dis[s] + edge[i].w;  //当前结点最长路径
        dfs(Eiv);
    }
}
//DFS版

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
const int MAXN = 5e4+5;
int dis[MAXN], fa[MAXN];
int head[MAXN], cnt;
int N, M, ans;

struct Edge
{
    int v, w, nxt;
    Edge(int _v = 0, int _w = 0, int _nxt = 0):v(_v), w(_w), nxt(_nxt){};
}edge[MAXN<<1];

void AddEdge(int from, int to, int weight)
{
    edge[cnt] = Edge(to, weight, head[from]);
    head[from] = cnt++;
}

void init()
{
    memset(head, -1, sizeof(head));
    for(int i = 0; i <= N; i++) fa[i] = i;
    cnt = 0;
    ans = 0;
}

void dfs(int s)
{
    for(int i = head[s]; i != -1; i = edge[i].nxt){
        int Eiv = edge[i].v;
        if(fa[s] == Eiv) continue; //不走回头路,也可以递归父亲结点省去fa数组空间
        fa[Eiv] = s;
        dis[Eiv] = dis[s] + edge[i].w;  //当前结点最长路径
        dfs(Eiv);
    }
}

int main()
{
    while(~scanf("%d%d", &N, &M))
    {
        init();
        char ccc;
        for(int i = 1, u, v, w; i <= M; i++){
            scanf("%d%d%d %c", &u, &v, &w, &ccc);
            AddEdge(u, v, w);
            AddEdge(v, u, w);
        }
        //printf("%d\n", ans);
        int ans_max = 0, ans_index = 0;
        dfs(1);                         //第一次dfs找出树的直径所在的点
        for(int i = 1; i <= N; i++){
            if(dis[i] > ans_max){
                ans_max = dis[i];
                ans_index = i;
            }
            dis[i] = 0;
            fa[i] = i;
        }

        dfs(ans_index);                 //第二次dfs找出树的直径
        for(int i = 1; i <= N; i++){
            if(dis[i] > ans_max) ans_max = dis[i];
        }
        printf("%d\n", ans_max);
    }
    return 0;
}

floyd的核心代码

  Floyd-Warshall Algorithm
//用来求两点间最短距离
      for (int k=0; k<10; ++k)
          for (int i=0; i<10; ++i)
              for (int j=0; j<10; ++j)
                d[i][j] = min(d[i][j], d[i][k] + d[k][j]);

    直徑也可以這樣算,在求出的各点最短路后就可找树的直径了
     for (int i=0; i<10; ++i)
         for (int j=0; j<10; ++j)
             diameter = max(diameter, d[i][j]);

bfs的核心代码

#include<iostream>
#include<stdio.h>
#include<map>
#include<vector>
#include<set>
#include<cstdlib>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<cmath>
#define MAXN 5000000
#define LL long long
#define EPS 1e-9
using namespace std;
struct Edge{
	int to;
	int next;
	int w;
}e[MAXN];
int tot,n,max_num,u,v,mst,med;
int dis[MAXN];
bool vis[MAXN];
int head[MAXN];
void init()
{
	tot=0;
	for(int i=1;i<=n;i++)
	{
		head[i]=-1;
	}
}
void add(int from,int to,int w)
{
	e[tot].to=to;
	e[tot].w=w;
	e[tot].next=head[from];
	head[from]=tot++;
}
int maxd;
void bfs(int st)
{
	queue<int>q;
	int i,now,next;
	memset(vis,false,sizeof(vis));
	memset(dis,0,sizeof(dis));
	vis[st]=true;
	q.push(st);
	maxd=0;
	dis[st]=0;
	while(!q.empty())
	{
		now=q.front();
		q.pop();
		for(i=head[now];i!=-1;i=e[i].next)
		{
			int v=e[i].to;
			if(!vis[v])
			{
				vis[v]=true;
				dis[v]=e[i].w+dis[now];
				if(maxd<dis[v])
				{
					max_num=v;
					maxd=dis[v];
				}
				q.push(v);
			}
		}
	}
}
int main()
{
	while(cin>>n)
	{
		if(n==1) {
		cout<<"0";break;} 
		init();
		for(int i=1;i<=n-1;i++)
		{
			cin>>u>>v;
			add(u,v,1);
			add(v,u,1);
		}
		bfs(1);
		mst=max_num;
		bfs(mst);
		cout<<maxd+1<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mlm5678/article/details/88318932