1034 Head of a Gang(DFS)
题意描述
由通话信息来判断几人是否位于一个帮派
输入输出格式
输入通话记录 输出 帮派的个数 以及每个帮派的头目和人数
数据规模
算法设计
这里使用DFS求解,这个DFS模型是比较经典的。我们使用DFS搜索图结构时,一般函数的参数第一个是当前访问的结点编号,之后的参数便是问题的信息,注意,这些参数一般是引用型的,会随着搜索实时更新,引用主函数变量,而且一经绑定便不会变化。函数处理的逻辑是 先将flag[i]
置true
表示 这个结点已经访问 若不置true
会导致循环访问 之后 访问结点 更新答案参数 之后 剪枝 之后开始扩展 即开始枚举与该结点有边相连的点 若结点还未访问 则一次去DFS
访问 这里要注意的是 我们访问flag[i] == false
的结点 是为了避免重复搜索 但如果像此题 要统计整个帮派的边权 显然不应当由flag[i]
的值决定 应该是一旦两个点有边 就将其权值加入到totalvalue
中 显然 最后 totalvalue
的值是真实值的2倍 而且 访问序列中初始值应该为第一个访问的结点 在扩展DFS
时,可以看作是要去访问这个相邻结点以及它们之间的边,若要搜寻路径,可以在这个阶段将其push进去,回溯时再进行pop 进入下一层DFS时就先更新答案
c++11代码
#include <bits/stdc++.h>
using namespace std;
using gg = long long;
struct node{
string u;
gg weight;
};
unordered_map<string,vector<node>>adj; // 邻接表
unordered_map<string,gg>weight; // 点的点权
unordered_map<string,bool>flag;
map<string,gg>res;
void DFS(string u, string& head, gg& num, gg& totalvalue){
flag[u] = true;
if(weight[u] > weight[head]) head = u;
for(auto& i : adj[u]){
totalvalue += i.weight;
if(not flag[i.u]) {
num++;
DFS(i.u, head, num, totalvalue);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
gg n, k, time, totalvalue, num;
string a, b, head;
cin>>n>>k;
while(n--){
cin>>a>>b>>time;
adj[a].push_back({b,time});
adj[b].push_back({a,time});
weight[a] += time;
weight[b] += time;
}
for(auto& i : weight){
if(not flag[i.first]){
head = "", num = 1, totalvalue = 0;
DFS(i.first, head, num, totalvalue);
if(num > 2 and totalvalue / 2 > k) res[head] = num;
}
}
cout<<res.size()<<"\n";
for(auto i : res) cout<<i.first<<" "<<i.second<<"\n";
return 0;
}