1034 Head of a Gang (30 分)图的dfs,有点像那个中风核区

1⃣️题目要求输出头目和人数,可以将权值最大的结点和其成员数目放到一个结构体数组中,但是,题目要求按照字典许输出,map正好会按照键的大小从小到大排序。键和值是一一对应的,所以一个建只能对应一个值
2⃣️将人变成结点,就要将名字转化成数字,可以用hash字符串转换成26进制,这样的话只能用链表存储边,不如直接人从0开始编号,在矩阵中连续存储,这样也与结点权值weight下标编号与人编号一一对应
3⃣️图的dfs,矩阵(二维数组),权值(一维数组),遍历标志(bool型一维数组)必备
4⃣️dfs和dfstrave模板根据题目要求添加需要的变量

#include<iostream>
#include<map>
#include<string>
using namespace std;
const int MAXN=2010;
const int INF=1010;
map<int,string> toname;
map<string,int> toid,gangnum;
int G[MAXN][MAXN]={
    
    0},weight[MAXN]={
    
    0};
int n,k,sum=0;
bool isvisit[MAXN]={
    
    false};
void dfs(int now,int &head,int &member,int &total){
    
    
    member++;
    isvisit[now]=true;
    if(weight[now]>weight[head])
        head=now;
    for(int i=0;i<sum;i++){
    
    
        if(G[now][i]>0){
    
    
            total+=G[now][i];
            G[now][i]=G[i][now]=0;
            if(isvisit[i]==false)
                dfs(i,head,member,total);
        }
    }
}
void dfstrave(){
    
    
    for(int i=0;i<sum;i++){
    
    
        if(isvisit[i]==false){
    
    
            int head=i,member=0,total=0;
            dfs(i,head,member,total);
            if(member>2&&total>k)
                gangnum[toname[head]]=member;
        }
    }
}
int change(string str){
    
    
    if(toid.find(str)!=toid.end())
        return toid[str];
    else{
    
    
        toid[str]=sum;
        toname[sum]=str;
        return sum++;
    }
}
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;
    }
    dfstrave();
    cout<<gangnum.size()<<endl;
    map<string,int>::iterator it;
    for(it=gangnum.begin();it!=gangnum.end();it++)
    {
    
    
        cout<<it->first<<" "<<it->second<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42835526/article/details/113901399