pat1034Head of a Gang (30)

题意分析:

(1)给出若干条通话记录(包括通话的两端的ID、时长),通过通话记录找出其中有多少个团伙,以及每个团伙的首领和团伙人数,所谓团伙就是指通过话的“联通”组织超过三人,可以理解为连通分量的人数超过三人,且集体通话时长超过一个给定的阈值。团伙首领是指在这个团伙中,这个人的通话时长最长

(2)此题的目标是寻找满足权值超过阈值、节点数超过2的联通分量,最简单的方法就是通过深度优先搜索遍历整个图;要寻找权值最大的节点,需要对每个节点维护其通话时长,由于一条通话的对端通话时长相等,因此最终的连通分量的权值是这些节点权值的一半。

(3)由于每个人的ID是通过字符串给出的,需要离散化。遍历的过程中需要实时更新权值最大的节点,使用map容器来完成对图的构建,以及使用map来对节点权值的索引;可以说此题就是在考察对map的灵活使用,当要遍历某个数据结构的时候,如果要检索的索引是字符串,就要考虑使用map,并且使用map来存储数据,天然已经按字符串的字典序排好了。最后输出的时候避免排序。

可能坑点:

(1)不要忘记最后所得连通分量的权值为所有节点权值的一半

#include 
#include 
#include 
#include 
using namespace std;

string head;
int cnt,total;
mapweight;
mapvisit;
map >adjlist;
mapres;

void DFS(string start)
{
    visit[start]=1;
    cnt++;
    total+=weight[start];
    if(weight[start]>weight[head])head=start;
    vector::iterator it=adjlist[start].begin();

    for(;it!=adjlist[start].end();it++)
    {
       if(visit[*it]==0)
       {
           DFS(*it);
       }
    }
}
int main()
{
    int N,K,T,i=0;
    cin>>N>>K;
    string member1,member2;
    while(i>member1>>member2>>T;
        weight[member1]+=T;
        weight[member2]+=T;
        adjlist[member1].push_back(member2);
        adjlist[member2].push_back(member1);
        visit[member1]=0;
        visit[member2]=0;
        i++;
    }

    map::iterator ite=visit.begin();
    for(;ite!=visit.end();ite++)
    {
        if(ite->second==0)
        {
            total=0;
            cnt=0;
            head=ite->first;
            DFS(ite->first);
        }
        if(cnt>2&&total/2>K)res[head]=cnt;
    }
    map::iterator it=res.begin();
    cout<first<<" "<second<
本文参考: http://blog.csdn.net/iaccepted/article/details/20161235

你可能感兴趣的:(PAT,C++)