SRM 584 Div II Level Two: Egalitarianism,DFS,BFS算法

题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12613&rd=15696


这个题目应该是一道典型的利用DFSBFS的题目,将每个人看成是图中的点,Friend关系看成图的边

用DFS判断该图是否是连通图,如果该图不是连通图,则说明其中至少有一个人是孤立的,也就是他的值可以为

任意数,即应返回 -1。

用BFS搜索两个点间最小距离的最大值,实际上就是权值为1情况下的Dijk算法,当然可以用Floyd算法,但图比

稀疏时,用Dijk算法更好。

代码如下:

#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

typedef struct entry {
	int p;			/* 图中点位置 */
	int deep;		/* bfs 深度 */
} entry;

class Egalitarianism {
private:
	vector <string> isFriend;
	vector <int> total;
	vector <bool> visited;
	bool dfs();
	int bfs(int p);
public:
	int maxDifference(vector <string> isFriend, int d);
};

/**
 * 判断是否是连通图
 */
bool Egalitarianism::dfs()
{
	stack <int> S;
	bool flag = true;
	S.push(0);
	while (!S.empty()) {
		int p = S.top();
		visited[p] = true;
		flag = true;
		for (int i = 0; i < isFriend.size(); i++) {
			if (!visited[i] && 'Y' == isFriend[p][i]) {
				visited[i] = true;
				S.push(i);
				flag = false;
				break;
			}
		}
		if (flag) {
			S.pop();
		}
	}
	for (int i = 0; i < isFriend.size(); i++) {
		if (!visited[i]) {
			return false;
		}
	}
	return true;
}

/**
 * 参数p表示从第p个人开始搜索,返回值为图(无权图)中各点到p的最小距离中的最大值
 */
int Egalitarianism::bfs(int p)
{
	queue < entry > Q;
	vector <int> total(isFriend.size());
	entry en;
	int md;

	for (int i = 0; i < isFriend.size(); i++) {
		total[i] = 0;
	}

	en.p = p;
	en.deep = 0;
	visited[p] = true;
	Q.push(en);
	while ( !Q.empty() ) {
		entry cus_p = Q.front();
		entry next_p = cus_p;
		Q.pop();
		++next_p.deep;
		for (int i = 0; i < isFriend.size(); i++) {
			if ( !visited[i] && 'Y' == isFriend[cus_p.p][i] ) {
				visited[i] = true;
				next_p.p = i;
				Q.push(next_p);
				total[i] = next_p.deep;
			}
		}
	}
	md = 0;
	for (int i = 0; i < isFriend.size(); i++) {
		if (total[i] > md) {
			md = total[i];
		}
	}
	return md;
}

int Egalitarianism::maxDifference(vector<string> isFriend, int d)
{
	this->isFriend = isFriend;
	int num = this->isFriend.size();
	int ans;
	for (int i = 0; i < num; i++) {
		visited.push_back(false);
	}
	if ( !dfs() ) {
		return -1;
	}

	ans = 0;
	for (int i = 0; i < num; i++) {
		for (int j = 0; j < num; j++) {
			visited[j] = false;
		}
		ans = max(ans, bfs(i));
	}

	return ans * d;
}

/* 测试 */
int main()
{
	string s[] = 	{"NYYN", "YNYN", "YYNN", "NNNN"};

	Egalitarianism E;
	vector <string> ss;
	for (int i = 0; i < sizeof(s) / sizeof(s[0]); i++) {
		ss.push_back(s[i]);
	}
	int d = 1;
	cout << E.maxDifference(ss, d) << endl;

	return 0;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值