浙大 PAT Advanced level 1021. Deepest Root (25)

A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent nodes' numbers.

Output Specification:

For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print "Error: K components" where K is the number of connected components in the graph.

Sample Input 1:
5
1 2
1 3
1 4
2 5
Sample Output 1:
3
4
5
Sample Input 2:
5
1 3
1 4
2 5
3 4
Sample Output 2:

Error: 2 components


将不含环的图作为一颗树,求让树高度最大的所有根节点。求树的高度很明显可以用bfs。

可以遍历图的每一个节点求高度,然后输出所有高度最大的节点。但需要注意case中有许多稀疏图,只有用邻接表的方式才可以通过所有case,用二维数组表示树在遍历过程中会超时。

实际上更简单的想法是,首先选取任一一个节点做bfs,并记录下使得树高度最高的所有顶点的集合set1,然后从set1中任选一点做bfs,记录下所有使得树高度最高的顶点结合set2,set1和set2的并集即为最终的结果。


/*
可以AC,效率很高 
0	答案正确	1	256	13/13
1	答案正确	1	296	2/2
2	答案正确	2	304	5/5
3	答案正确	23	1536	2/2
4	答案正确	1	256	2/2
5	答案正确	1	256	1/1
*/ 

#include <iostream>
#include <vector>
#include <queue>
#include <set>
using namespace std;

const int white = 0;
const int gray = 1;
const int black = 2;
typedef struct node
{
	int color;
	int height;
	vector<int> adj;
}node;
int N;
vector<node> graph;


void dfs(int index)
{
	int k;
	graph[index].color = gray;
	for (unsigned int i = 0; i < graph[index].adj.size(); ++i)
	{
		k = graph[index].adj[i];
		if (white == graph[k].color)
		{
			dfs(k);
		}
	}
	graph[index].color = black;
}

void bfs(int root, vector<int> &res)
{
	int max_height = 0;
	int index;
	int k;
	queue<int> nq;

	for (int i = 0; i != N; ++i)
	{
		graph[i].color = white;
		graph[i].height = 0;
	}

	nq.push(root);
	graph[root].color = gray;
	while (!nq.empty())
	{
		index = nq.front();
		nq.pop();
		graph[index].color = black;
		for (unsigned int i = 0; i != graph[index].adj.size(); ++i)
		{
			k = graph[index].adj[i];
			if (white == graph[k].color)
			{
				graph[k].height = graph[index].height + 1;
				graph[k].color = gray;
				nq.push(k);
				if (graph[k].height > max_height)
				{
					max_height = graph[k].height;
				}
			}
		}
	}


	for (int i = 0; i != N; ++i)
	{
		if (graph[i].height == max_height)
		{
			res.push_back(i);
		}
	}
	return ;
}

int main()
{
	int ni, nj;
	vector<int> res1, res2;
	set<int> res_all;
	int parts = 0;
	bool flag = false;

	cin >> N;
	graph.resize(N);
	for (int i = 0; i != N; ++i)
	{
		graph[i].color = white;
		graph[i].height = 0;
	}

	for (int i = 0; i != N-1; ++i)
	{
		cin >> ni >> nj;
		--ni;
		--nj;
		graph[ni].adj.push_back(nj);
		graph[nj].adj.push_back(ni);
	}
	

	for (int i = 0; i != N; ++i)
	{
		if (white == graph[i].color)
		{
			dfs(i);
			++parts;
		}
	}

	if (1 != parts)
	{
		cout << "Error: " << parts << " components" << endl;
		return 0;
	}

	bfs(0, res1);
	bfs(res1.at(0), res2);
	ni = nj = 0;
	
	for (unsigned int i = 0; i != res1.size(); ++i)
	{
		res_all.insert(res1[i]);
	}
	for (unsigned int i = 0; i != res2.size(); ++i)
	{
		res_all.insert(res2[i]);
	}
	for (set<int>::const_iterator iter = res_all.begin(); iter != res_all.end(); ++iter)
	{
		cout << (*iter)+1 << endl;
	}
	
	return 0;
}


/* 可以ac
0	答案正确	1	256	13/13
1	答案正确	1	256	2/2
2	答案正确	1	300	5/5
3	答案正确	984	1212	2/2
4	答案正确	1	256	2/2
5	答案正确	1	316	1/1
*/
/* 稀疏图用邻接表效率更高*/
#if 0
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int white = 0;
const int gray = 1;
const int black = 2;
typedef struct node
{
	int color;
	int start;
	int finish;
	int height;
	vector<int> adj;
}node;
int N;
vector<node> graph;
int ntime = 0;
int parts = 0;

void dfs(int index)
{
	int k;
	graph[index].color = gray;
	graph[index].start = ntime++;
	for (unsigned int i = 0; i < graph[index].adj.size(); ++i)
	{
		k = graph[index].adj[i];
		if (white == graph[k].color)
		{
			dfs(k);
		}
	}
	graph[index].color = black;
	graph[index].finish = ntime++;
}

int bfs(int root)
{
	int ret = 0;
	int index;
	int k;
	queue<int> nq;

	for (int i = 0; i != N; ++i)
	{
		graph[i].color = white;
		graph[i].height = 0;
	}
	
	nq.push(root);
	graph[root].color = gray;
	while (!nq.empty())
	{
		index = nq.front();
		nq.pop();
		graph[index].color = black;
		for (unsigned int i = 0; i != graph[index].adj.size(); ++i)
		{
			k = graph[index].adj[i];
			if (white == graph[k].color)
			{
				graph[k].height = graph[index].height + 1;
				graph[k].color = gray;
				nq.push(k);
				if (graph[k].height > ret)
				{
					ret = graph[k].height;
				}
			}
		}
	}
	return ret;
}

int main()
{
	int ni, nj, nh;
	int max_height = 0;
	vector<int> results;

	cin >> N;
	graph.resize(N);
	for (int i = 0; i != N; ++i)
	{
		graph[i].color = white;
		graph[i].height = 0;
	}
	for (int i = 0; i != N-1; ++i)
	{
		cin >> ni >> nj;
		--ni;
		--nj;
		graph[ni].adj.push_back(nj);
		graph[nj].adj.push_back(ni);
	}

	for (int i = 0; i != N; ++i)
	{
		if (white == graph[i].color)
		{
			dfs(i);
			++parts;
		}
	}

	
	if (1 != parts)
	{
		cout << "Error: " << parts << " components" << endl;
	}
	else
	{
		for (int i = 0; i != N; ++i)
		{
/************************************************************************/
/* 注释掉下面的if 语句可以ac											*/
/* 考虑输入:2 1 2														*/
/************************************************************************/
			/* if (graph[i].start + 1 == graph[i].finish) */
			{
				nh = bfs(i);
				if (nh > max_height)
				{
					max_height = nh;
					results.clear();
					results.push_back(i);
				}
				else
				{
					if (nh == max_height)
					{
						results.push_back(i);
					}
				}
			}
		}

		for (unsigned int i = 0; i != results.size(); ++i)
		{
			cout << results[i]+1 << endl;
		}
	}
	
	return 0;
}

#endif


#if 0
// 超时
#include <iostream>
#include <queue>
using namespace std;

int graph[10002][10002];				/* 1表示存在路径*/
int visited[10002];						/* 1为已经访问*/
int result[10002];

void DFS(int root, int num)
{
	visited[root] = true;
	for (int i = 1; i <= num; ++i)
	{
		if (1 == graph[root][i] && 0 == visited[i])
		{
			DFS(i, num);
		}
	}
}

// 返回正值表示以root为根的树的最大深度
// 返回负值表示图有多少个不连通的部分
int levelCount(int root, int num)
{
	int level;						// 记录以root为根的树的最大深度
	int part;						// 记录图有多少个相互不连通的区域(针对"Error: K components") 
	bool flag = true;				// 如果是连通图, 则为true; 反之为false
	int count, temp;
	queue<int> Q;
	for (int i = 1; i <= num; ++i)
	{
		visited[i] = 0;
	}

	Q.push(root);
	count = 1;
	level = 0;
	visited[root] = 1;
	part = 1;

	while(!Q.empty())
	{
		while(count--)
		{
			temp = Q.front();
			Q.pop();
			for (int i = 1; i <= num; ++i)
			{
				if (1 == graph[temp][i] && 0 == visited[i])
				{
					visited[i] = 1;
					Q.push(i);
				}
			}
		}
		count = Q.size();
		++level;
	}
	for (int i = 1; i <= num; ++i)
	{
		// 存在未被访问的点
		if (0 == visited[i])
		{
			flag = false;
			DFS(i, num);
			++part;
		}
	}
	if (flag)
	{
		return level;
	}
	else
	{
		return -part;
	}
}

int main()
{
	int num;
	int row, col;
	int maxlevel = 0;
	cin >> num;
	for (int i = 1; i != num; ++i)
	{
		cin >> row >> col;
		graph[row][col] = graph[col][row] = 1;
	}
	for (int i = 1; i <= num; ++i)
	{
		result[i] = levelCount(i, num);
		if (result[i] < 0)
		{
			cout << "Error: " << -result[i] <<  " components" << endl;
			system("pause");
			return 0;
		}
		if (result[i] > maxlevel)
		{
			maxlevel = result[i];
		}
	}

	for (int i = 1; i <= num; ++i)
	{
		if (result[i] == maxlevel)
		{
			cout << i << endl;
		}
	}
	
	system("pause");
	return 0;
}

#endif


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值