A1034 Head of a Gang (30分)
一、技术总结
- 这一题是关于图的遍历的,首先拿到题目理解题意,可以发现第一个需要考虑的问题是如何存储的问题。
- 然后就是考虑使用哪种遍历方法的问题,这里使用DFS遍历的方法。
- 然后还有就是如何存储字符串和编号的问题,使用
map<string, int>
,进行解决。最后就是关于统计每一个连通分量是否达标,一个是人数,一个是阀值。所以需要重新开辟一个空间来进行记录。也是使用map,用权重最大的字符串,进行对应的人数。 - 同时如果使用邻接矩阵,和一个bool数组用于记录结点是否被访问过是常规操作。
- 对于DFS函数,需要考虑的就是参数问题,这一题中一个当前结点编号为一个i参数,还有就是head作为记录权值最大的一个作为参数,在一个就是记录人数numMember作为参数,再一个就是totalValue,总权值相加看是否达到阀值。
- 其余细节参考代码
二、参考代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2010;
const int INF = 1000000000;
map<int, string> intToString;//编号->姓名
map<string, int> stringToInt;//姓名->编号
map<string, int> Gang;//head->人数
int G[maxn][maxn] = {0}, weight[maxn] = {0};//邻接矩阵和点权weight
int n, k, numPerson;//边数n,下限k, 总人数numPerson
bool vis[maxn] = {false};//标记是否被访问
//DFS函数访问单个连通块,nowVisit为当前访问的编号
//head为头目,numMember为成员编号,totalValue为连通块的总边权
void DFS(int nowVisit, int& head, int& numMember, int& totalValue){
numMember++;//成员人数加一
vis[nowVisit] = true;//标记为已访问
if(weight[nowVisit] > weight[head]){
head = nowVisit;
}
for(int i = 0; i < numPerson; i++){
if(G[nowVisit][i] > 0){
totalValue += G[nowVisit][i];//连通块的总边权增加该边权
G[nowVisit][i] = G[i][nowVisit] = 0;
if(vis[i] == false){
DFS(i, head, numMember, totalValue);
}
}
}
}
//DFSTrace函数遍历整个图
void DFSTrace(){
for(int i = 0; i < numPerson; i++){
if(vis[i] == false){
int head = i, numMember = 0, totalValue = 0;//头目、成员数、总边权
DFS(i, head, numMember, totalValue);
if(numMember > 2 && totalValue > k){
//head人数为numMember
Gang[intToString[head]] = numMember;
}
}
}
}
//change函数返回姓名str对应的编号
int change(string str){
if(stringToInt.find(str) != stringToInt.end()){
return stringToInt[str];
}else{
stringToInt[str] = numPerson;
intToString[numPerson] = str;
return numPerson++;
}
}
int main(){
int w;
string str1, str2;
cin >> n >> k;
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;
}
DFSTrace();
cout << Gang.size() << endl;
for(auto it = Gang.begin(); it != Gang.end(); it++){
cout << it->first << " " << it->second << endl;
}
return 0;
}
作者:睿晞
身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
曾有一个业界大牛说过这样一段话,送给大家:
“华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.