A1034 Head of a Gang (30分)

Posted tsruixi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A1034 Head of a Gang (30分)相关的知识,希望对你有一定的参考价值。

一、技术总结

  1. 这一题是关于图的遍历的,首先拿到题目理解题意,可以发现第一个需要考虑的问题是如何存储的问题。
  2. 然后就是考虑使用哪种遍历方法的问题,这里使用DFS遍历的方法。
  3. 然后还有就是如何存储字符串和编号的问题,使用map<string, int>,进行解决。最后就是关于统计每一个连通分量是否达标,一个是人数,一个是阀值。所以需要重新开辟一个空间来进行记录。也是使用map,用权重最大的字符串,进行对应的人数。
  4. 同时如果使用邻接矩阵,和一个bool数组用于记录结点是否被访问过是常规操作。
  5. 对于DFS函数,需要考虑的就是参数问题,这一题中一个当前结点编号为一个i参数,还有就是head作为记录权值最大的一个作为参数,在一个就是记录人数numMember作为参数,再一个就是totalValue,总权值相加看是否达到阀值。
  6. 其余细节参考代码

二、参考代码

#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;
}

以上是关于A1034 Head of a Gang (30分)的主要内容,如果未能解决你的问题,请参考以下文章

1034 Head of a Gang (30)(30 分)

1034 Head of a Gang (30 分)

1034 Head of a Gang (30分)

PAT 甲级 1034 Head of a Gang (30 分)(bfs,map,强连通)

1034 Head of a Gang (30 分) 难度: 中 / 知识点: 并查集

PAT 1034 Head of a Gang[难]