PAT-1034-连通分量+权值问题

//题目大意:输入多个电话联线,找出总权和超过阈值的组,并按点权最大输出头目——————深搜过程中找到。
//输入 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设我们有以下带权值的二叉树: ``` 2 / \ 6 4 / \ \ 8 3 5 ``` 在使用best-first-search算法进行搜索时,我们需要根据节点的权值来确定搜索的优先级。假设我们从根节点开始搜索,那么根节点的权值为2,它将会被放入open表中。此时open表中的内容如下: ``` 2 ``` 接下来,我们需要从open表中选取权值最小的节点进行扩展。因此,我们选择根节点进行扩展。根节点有两个子节点,即6和4,它们的权值分别为6和4。我们将这两个子节点按照权值的大小依次放入open表中,此时open表的内容如下: ``` 4, 6 ``` 接下来,我们从open表中选取权值最小的节点进行扩展。因此,我们选择4进行扩展。4只有一个子节点5,它的权值为5,于是我们将5放入open表中。此时open表的内容如下: ``` 5, 6 ``` 接下来,我们从open表中选取权值最小的节点进行扩展。因此,我们选择5进行扩展。5没有子节点,因此它被标记为已经被扩展。此时open表的内容如下: ``` 6 ``` 接下来,我们从open表中选取权值最小的节点进行扩展。因此,我们选择6进行扩展。6有两个子节点,即8和3,它们的权值分别为8和3。我们将这两个子节点按照权值的大小依次放入open表中,此时open表的内容如下: ``` 3, 8 ``` 接下来,我们从open表中选取权值最小的节点进行扩展。因此,我们选择3进行扩展。3没有子节点,因此它被标记为已经被扩展。此时open表的内容如下: ``` 8 ``` 接下来,我们从open表中选取权值最小的节点进行扩展。因此,我们选择8进行扩展。8没有子节点,因此它被标记为已经被扩展。此时open表的内容为空,搜索结束。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值