【PAT Advanced Level】1021. Deepest Root (25)

这题分两个步骤:

1. 求出图中有几个连通子图

2. 如果只有一个连通图,找出最长的路径(图的直径)

我直接用了一个DFS求连通子图的个数,其实更通用的方法是并查集。

找出最长路径,我们进行了n次DFS,每次以一个节点作为根节点。后来看了网上的解法,其实只需要两次DFS就可以求得。

昨天我刚刚看了怎么求树的直径,今天该用到的时候又忘了,真是学的不牢啊。具体求法见http://blog.csdn.net/gzxcyy/article/details/14165829

//一次DSF即可
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;

int num;
vector<vector<int>> adj;
vector<int> visited;
vector<int> deepest;
vector<int> distances;
int connected = 0;

void DSF_VISIT(int i)
{
	visited[i] = 1;
	for(int j = 0; j < adj[i].size(); j++)
	{
		if(!visited[adj[i][j]])
		{
			distances[adj[i][j]] = distances[i] + 1;
			DSF_VISIT(adj[i][j]);
		}
	}
	visited[i] = 2;
}

void DSF()
{
	for(int i = 1; i <= num; i++)
	{
		if(!visited[i])
		{
			DSF_VISIT(i);
			connected++;
		}
	}
}

int main()
{
	//fstream cin("a.txt");
	cin>>num;
	int tmp = num - 1;
	adj.assign(num + 1, vector<int>());
	visited.assign(num + 1, 0);
	deepest.assign(num + 1, 0);
	distances.assign(num + 1, 0);
	int a,b;
	while (tmp--)
	{
		cin>>a>>b;
		adj[a].push_back(b);
		adj[b].push_back(a);
	}
	DSF();
	if(connected > 1)
		cout<<"Error: "<<connected<<" components"<<endl;
	else
	{
		for(int i = 1; i <= num; i++)
		{
			visited.assign(num + 1, 0);
			distances.assign(num + 1, 0);
			DSF_VISIT(i);
			vector<int>::iterator it = max_element(distances.begin(), distances.end());
			deepest[i] = *it;
		}
		vector<int>::iterator it = max_element(deepest.begin(), deepest.end());
		for(int i = 1; i < deepest.size(); i++)
		{
			if(deepest[i] == *it)
				cout<<i<<endl;
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值