题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12613&rd=15696
这个题目应该是一道典型的利用DFS和BFS的题目,将每个人看成是图中的点,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;
}