您的位置:首页 > 其它

pat1034Head of a Gang (30)

2015-10-10 18:30 316 查看
题意分析:

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

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

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

可能坑点:

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

#include <iostream>
#include <string.h>
#include <map>
#include <vector>
using namespace std;

string head;
int cnt,total;
map<string,int>weight;
map<string,bool>visit;
map<string,vector<string> >adjlist;
map<string,int>res;

void DFS(string start)
{
visit[start]=1;
cnt++;
total+=weight[start];
if(weight[start]>weight[head])head=start;
vector<string>::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<N)
{
cin>>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<string,bool>::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<string,int>::iterator it=res.begin();
cout<<res.size()<<endl;
for(;it!=res.end();it++)cout<<it->first<<" "<<it->second<<endl;
return 0;
}
本文参考:/article/1439602.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: