One way that the police finds the head of a gang is to check people's phone calls. If there is a phone call between A and B, we say that A and B is related. The weight of a relation is defined to be the total time length of all the phone calls made between the two persons. A "Gang" is a cluster of more than 2 persons who are related to each other with total relation weight being greater than a given threshold K. In each gang, the one with maximum total weight is the head. Now given a list of phone calls, you are supposed to find the gangs and the heads.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers N and K (both less than or equal to 1000), the number of phone calls and the weight threshold, respectively. Then N lines follow, each in the following format:

Name1 Name2 Time

where Name1 and Name2 are the names of people at the two ends of the call, and Time is the length of the call. A name is a string of three capital letters chosen from A-Z. A time length is a positive integer which is no more than 1000 minutes.

Output Specification:

For each test case, first print in a line the total number of gangs. Then for each gang, print in a line the name of the head and the total number of the members. It is guaranteed that the head is unique for each gang. The output must be sorted according to the alphabetical order of the names of the heads.

Sample Input 1:

8 59
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10

Sample Output 1:

2
AAA 3
GGG 3

Sample Input 2:

8 70
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10

Sample Output 2:

0
 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
map<string , int> mp1;
map<int, string>mp2;
map<string, int> ans;
int G[][] = {}, personNum = , time_[] = {};
int N, K, visit[] = {};
int str2num(string ss){
if(mp1.count(ss) == ){
mp1[ss] = personNum;
mp2[personNum] = ss;
return personNum++;
}else return mp1[ss];
}
void dfs(int v, int &sum, int &head, int &cnt){
visit[v] = ;
cnt++;
if(time_[head] < time_[v])
head = v;
for(int i = ; i < personNum; i++){
if(G[v][i] != ){
sum += G[v][i];
G[v][i] = G[i][v] = ;
if(visit[i] == )
dfs(i, sum, head, cnt);
}
}
}
int main(){
//std::ios::sync_with_stdio(false);
cin >> N >> K;
string str1, str2;
int we;
for(int i = ; i < N; i++){
cin >> str1 >> str2 >> we;
int e1 = str2num(str1);
int e2 = str2num(str2);
G[e1][e2] += we;
G[e2][e1] += we;
time_[e1] += we;
time_[e2] += we;
}
int gangs = ;
for(int i = ; i < personNum; i++){
if(visit[i] == ){
int sum = , cnt = , head = i;
dfs(i, sum, head, cnt);
if(sum > K && cnt > ){
gangs++;
ans[mp2[head]] = cnt;
}
}
}
cout << gangs << endl;
map<string, int>::iterator it;
for(it = ans.begin(); it != ans.end(); it++){
cout << it->first << " " << it->second << endl;
}
return ;
}

总结:

1、题意:一个连通子图的节点数大于2,且它的边权的和大于K,就说明是gang,其中这个子图中与他人通话时长之和最多的节点被认为是头领。要求输出头领和该子图的节点个数。

2、首先是字符串作为节点的id需要被编号。起初看到只有3位想将其映射为26*26*26进制,但其实太大了而且有好多节点有可能是空的,这样从0遍历到26*26*26遍历的话时间上会超时。 所以只能使用map,映射从int到string,string到int。再使用一个计数器统一分配从0开始的节点编号。

3、由于深搜的原则是所有节点只遍历一次,使用了visit数组记录一个点是否被访问过。但本题实际上要求遍历连通图的所有边(获取整个gang的通话时长总和),如果仅仅按照点的方法遍历,很可能漏掉一些边。 所以

  • 要在判断遍历A的所有联通的点是否被visit了之前就先访问一次他们之间的边。
  • 其次为了防止回溯之后重复访问某条边,需要在累加完这条边之后立即置0。

第一种情况,深度搜索按照A->B->C的顺序访问节点,A时可以得到AB边,B时可以得到BC边,当访问C节点时,由于A被标记为visit,所以CA无法得到。这是回溯到A节点,A无法访问C(C被标记为visit),故AC边被漏掉了。

第二种情况,已经在判断visited之前加上了某条边,还会出重复访问某条边的情况。比如与之前类似,A->B->C的顺序访问,当访问到C时,由于这次是在判断visit之前先访问边,所以边CA被访问。结束后回溯到A,A再次测试C节点(不可访问,被标记visit),这是会再访问一次边AC,造成重复访问。

4、对于无向图,一定要对G[ i ][ j ]与G[ j ][ i ]同时操作。

5、本题判断谁是头目采用找点权最大的节点,这个可以在读入数据的时候就计算,不必等到遍历的时候。其次,由于是通话记录,所以可能会有多个A->B,B->A的记录,图上的边权是累加的而不是赋值(A->B需要给AB与BA边累加,B->A同样要给AB与BA累加)。

6、map<key, val>中,存储是按key递增的顺序记录的,遍历即可得到递增序列。

A1034. Head of a Gang的更多相关文章

  1. PAT A1034 Head of a Gang (30 分)——图遍历DFS,字符串和数字的对应保存

    One way that the police finds the head of a gang is to check people's phone calls. If there is a pho ...

  2. PAT_A1034#Head of a Gang

    Source: PAT A1034 Head of a Gang (30 分) Description: One way that the police finds the head of a gan ...

  3. PAT (Advanced Level) Practice(更新中)

    Source: PAT (Advanced Level) Practice Reference: [1]胡凡,曾磊.算法笔记[M].机械工业出版社.2016.7 Outline: 基础数据结构: 线性 ...

  4. PAT A1034 Head Of Gang

    用并查集分割团伙,判断输出~ #include<bits/stdc++.h> using namespace std; ; },weight[maxn]; unordered_map< ...

  5. 1034 Head of a Gang (30 分)

    1034 Head of a Gang (30 分) One way that the police finds the head of a gang is to check people's pho ...

  6. 1034. Head of a Gang (30)

    分析: 考察并查集,注意中间合并时的时间的合并和人数的合并. #include <iostream> #include <stdio.h> #include <algor ...

  7. [BZOJ1370][Baltic2003]Gang团伙

    [BZOJ1370][Baltic2003]Gang团伙 试题描述 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: ...

  8. Head of a Gang (map+邻接表+DFS)

    One way that the police finds the head of a gang is to check people's phone calls. If there is a pho ...

  9. 九度OJ 1446 Head of a Gang -- 并查集

    题目地址:http://ac.jobdu.com/problem.php?pid=1446 题目描述: One way that the police finds the head of a gang ...

随机推荐

  1. mysql [assword expired

    mysql 5.6 在使用Navicat在其他机器上进行远程登录数据库时 会出现 password expired ,需要重新设置一下密码. SET PASSWORD FOR 'root'@'%' = ...

  2. js中获取当前项目名等

    实际上通过window.location可以获取很多跟资源路径相关的信息,需要用到的时候直接通过浏览器调试可以查看window.location的一些属性

  3. Could not render e, see the console.

    错误截图: 解决: 在application.properties中开启swagger swagger2.enable=true

  4. Java多线程3:Thread中的实例方法

    一.Thread类中的方法调用方式 学习Thread类中的方法是学习多线程的第一步.在学习多线程之前特别提出一点,调用Thread中的方法的时候,在线程类中,有两种方式,一定要理解这两种方式的区别: ...

  5. jedis单机版应用

    1.pom文件添加依赖: 2.创建配置文件 创建单机版redisClient 代码: package com.skymall.rest.dao.imp; import org.springframew ...

  6. DeepLearning训练方法

    1.BN层训练技巧 缩小输入尺寸,这样可以提高batchsize的大小,在BN层适应了该数据集后,固定住BN层参数,放大输入尺寸继续训练 2.语义分割中解决网络输出尺寸与原尺寸的gap方法(如 1/8 ...

  7. poj-1273(最大流)

    题解:纯板子题... EK算法 #include<iostream> #include<algorithm> #include<cstring> #include& ...

  8. Linux vmstat命令

    vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况.这个命令是我查看Linux/Unix最 ...

  9. 配置 Django

    Django项目的设置文件位于项目同名目录下,名叫settings.py.这个模块,集合了整个项目方方面面的设置属性,是项目启动和提供服务的根本保证. 一.简述 settings.py文件本质上是一个 ...

  10. 常用的redis服务命令。

    卸载服务:redis-server --service-uninstall 开启服务:redis-server --service-start 停止服务:redis-server --service- ...