A1034. Head of a Gang
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的更多相关文章
- 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 ...
- 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 ...
- PAT (Advanced Level) Practice(更新中)
Source: PAT (Advanced Level) Practice Reference: [1]胡凡,曾磊.算法笔记[M].机械工业出版社.2016.7 Outline: 基础数据结构: 线性 ...
- PAT A1034 Head Of Gang
用并查集分割团伙,判断输出~ #include<bits/stdc++.h> using namespace std; ; },weight[maxn]; unordered_map< ...
- 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 ...
- 1034. Head of a Gang (30)
分析: 考察并查集,注意中间合并时的时间的合并和人数的合并. #include <iostream> #include <stdio.h> #include <algor ...
- [BZOJ1370][Baltic2003]Gang团伙
[BZOJ1370][Baltic2003]Gang团伙 试题描述 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌人的敌人是我的朋友: ...
- 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 ...
- 九度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 ...
随机推荐
- 定义一个内核panic问题
出现问题时的反汇编为: /usr/src/debug/kernel-4.1.44-.aarch64/net/core/dev.c: 17800xffff800000860724 <__netif ...
- 老男孩 python学习自修第二十二天【文件上传与下载】
1.使用socket实现文件上传 server.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import os import SocketServe ...
- Mvc校验用户没有登录就跳转的实现
看字面意思很简单,就是判断用户是否登录了,如果没有登录就跳转到登陆页面. 没错,主要代码如下(这里就不写判断登录了,直接跳转) 首先在控制器中新建一个BaseController public cla ...
- Ajax与CORS通信
处理跨域的主要方法 JSONP CORS 本文主要讨论CORS解决Ajax因为浏览器同源策略不能跨域请求数据的问题. 1. JSONP JSONP跨域可以参考下面这篇博客 JSONP跨域 2. COR ...
- Js 常用字符串操作 API
常用的一些字符串操作 API 整理 1.str.charAt(index).str.charCodeAt(index) - 返回指定位置的字符 / 字符编码(0~65535) index - 必须,表 ...
- ExportHandler.ashx
using KYZWeb.Common;using Liger.Data;//using Microsoft.Office.Interop.Excel;using System;using Syste ...
- string.Format出现异常:输入字符串的格式不正确 Exception during StringFormat
错误信息:Exception during StringFormat:输入字符串的格式不正确 “System.FormatException”类型的未经处理的异常在 mscorlib.dll 中发生 ...
- Spring Boot 构建电商基础秒杀项目 (八) 商品创建
SpringBoot构建电商基础秒杀项目 学习笔记 新建数据表 create table if not exists item ( id int not null auto_increment, ti ...
- axis函数
axis函数 axis([xmin xmax ymin ymax]) 用来标注输出的图线的最大值最小值. MATLAB中坐标系的设置函数 MATLAB 函数 axis([XMIN XMAX YMI ...
- Nginx log_format
L11 nginx 官网的日志格式如下 log_format compression(自定义名称) '$remote_addr - $remote_user [$time_local] ' '&quo ...