#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
#include <ctime>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef struct Record
{
int time;//与其他人通话的时间
int num;//该帮派中的总人数
int total;//该帮派中所有人的通话总时间
string name;//头目姓名
}Record;
const int MAX = 2010;//至多有1000条记录,所以涉及的人数共有两千人,否则会出现段错误
int Graph[MAX][MAX] = {0};//图的邻接矩阵表示,其数据表示两者的通话时间
Record Head[MAX] = {0};//存贮每个帮派的头目信息
int cnt = 0;
bool e_visited[MAX][MAX] = {0};//每条边是否被访问
bool v_visited[MAX] = {0};//每个顶点是否被访问
int N, K;
int id = 0;
map<string, int> name2id;
map<int, string> id2name;
int nameToID(string name)//把名字转为id号,并将对应的信息保存在map里
{
map<string, int>::iterator it = name2id.find(name);
if(it != name2id.end()) return it->second;
id2name[id] = name;
name2id[name] = id++;//id相当于一个计数器
return name2id[name];
}
void BFS(int v)//广度优先搜索
{
int time = 0;
queue<int> Q;
Q.push(v);
v_visited[v] = true;
while(!Q.empty())
{
time = 0;//该人与其他人的通话时间
v = Q.front();
Q.pop();
Head[cnt].num++;//该帮派中的总人数
for(int i=0; i<id; i++)
{
time += Graph[v][i];
if(Graph[v][i] && !e_visited[v][i])//该边未被访问,则记录总时间
{
Head[cnt].total += Graph[v][i];
e_visited[v][i] = true;
e_visited[i][v] = true;//并置已访问标记
if(!v_visited[i])//该顶点未访问则入队
{
Q.push(i);
v_visited[i] = true;
}
}
}
if(time > Head[cnt].time)//更新头目
{
Head[cnt].name = id2name[v];
Head[cnt].time = time;
}
}
}
bool cmp(Record A, Record B)//按帮派头目名字的字典序排序
{
return A.name < B.name;
}
int main()
{
int id1, id2, time;
string name1, name2;
scanf("%d %d", &N, &K);
for(int i=0; i<N; i++)
{
getchar();
cin>>name1>>name2>>time;
id1 = nameToID(name1);
id2 = nameToID(name2);
Graph[id1][id2] += time;//按无向图存贮即可
Graph[id2][id1] += time;
}
for(int i=0; i<id; i++)
{
if(!v_visited[i])//该顶点尚未访问,说明是图的一个连通分量
{
BFS(i);
if(Head[cnt].num > 2 && Head[cnt].total > K) cnt++;//该连通分量中的总人数和通话总时间满足要求,则帮派数++
else//否则数据清零
{
Head[cnt].total = 0;
Head[cnt].time = 0;
Head[cnt].num = 0;
}
}
}
printf("%d\n", cnt);
sort(Head, Head+cnt, cmp);//按帮派头目名字的字典序排序
for(int i=0; i<cnt; i++)
{
cout<<Head[i].name<<" "<<Head[i].num<<endl;
}
return 0;
}
PAT (Advanced Level) Practice A1034 Head of a Gang (30 分)(甲级)(C++)(图、BFS,map)
最新推荐文章于 2024-04-30 23:50:17 发布