//题目大意:输入多个电话联线,找出总权和超过阈值的组,并按点权最大输出头目——————深搜过程中找到。
//输入 n sum//阈值 n组连线。
//思路:邻接表记录点与点之间的关系。
//邻接矩阵也存放点与点的关系,如果是网,则存放边的权值,与点的权重无关(注意此题)!!!。
// 邻接矩阵具有普适性。
// 一维数组来存储点权值——以编号来记录点的信息(map映射编号和姓名。在输入数据时处理姓名与编号)。
// 最后要求总权值——用dfs遍历:对图的遍历。
//————记录:用一个map来记录头目与人数,判断达到阈值则输出——迭代器的使用。
// bool visit标记数组来标记是否遍历过该顶点。
#include<bits/stdc++.h>
#define MAXN 20005
using namespace std;
int weight[MAXN];
map<string, int> stoi_;
map<int, string> itos_;
map<string, int> sum_p;//————或者struct{name, num}[]
int n, k, numperson = 0; //numperson为总人数
bool visit[MAXN] = {false};
int G[MAXN][MAXN] = {0};
int change(string str){
if(stoi_.find(str) != stoi_.end()){
return stoi_[str];
}else {
stoi_[str] = numperson;
itos_[numperson] = str;
return numperson++;
}
}
//采用引用,深度遍历过程中查找head, nummember, totalvalue。————参数为所寻值。
void DFS(int nowvisit, int &head, int &nummember, int &totalvalue){
nummember++;
visit[nowvisit] = true;
if(weight[nowvisit] > weight[head]){
head = nowvisit; //更新头目
}
/*for(int i = 0; i < n; i++){
if(visit[i] == false){
DFS(i, head, nummember, totalvalue);
}
}*/
for(int i = 0; i < numperson; i++){ //枚举所有人
if(G[nowvisit][i] > 0){
totalvalue += G[nowvisit][i]; //————————区分遍历过此点和可达此点!
G[nowvisit][i] = G[i][nowvisit] = 0; //删边————防止回路重加
//嵌套在if(G[nowvisit][i] > 0)中保证可达,如果未曾遍历,进行深层遍历————加上此点为起点的nummember, totalvalue;
if(visit[i] == false){
DFS(i,head,nummember, totalvalue);
}
}
}
}
void DFSTrave(){
for(int i = 0; i < numperson; i++){
if(visit[i] == false){ //未曾遍历过此点
int head = i, nummember = 0, totalvalue = 0; //头目,连通分量人数,总权值
DFS(i, head, nummember, totalvalue);//找到头目遍历,总权值
if(nummember > 2 && totalvalue > k){//满足人数大于2,总权值大于k
sum_p[itos_[head]] = nummember;
}
}
}
}
int main(){
cin >> n >> k;
int w;
string str1, str2;
//如何建立起string与int对应关系————输入有重问题
for(int i = 0; i < n; i++){
cin >> str1 >> str2 >> w;
int id1 = change(str1);
int id2 = change(str2);
weight[id1]+=w;
weight[id2]+=w;
G[id1][id2] += w;
G[id2][id1] += w;
}
//map迭代器的使用
DFSTrave();
cout << sum_p.size() << endl;
map<string, int>::iterator it;
for(it = sum_p.begin(); it != sum_p.end(); it++)
cout << it->first << " " << it->second << endl;
return 0;
}
PAT-1034-连通分量+权值问题
最新推荐文章于 2020-05-29 22:53:13 发布