题意:给出一段通话记录 第一行 几条通话记录 成为犯罪团伙的通话最小时长
后面就是 代号1 代号2 通话时间。
题解:本题难度略大,出了要考虑是深搜以外,还需要考虑数据的存储问题,需要将字符与编号相互转换,整体思路就是将整个通话记录构建一张图,这个图当然是利用编号作为节点进行构建,然后再看连通子图是否满足其犯罪团伙的条件,满足还要记得排序 然后输出
共多少团伙
团伙头目 团伙共几人
如果没有团伙,输出0即可。
详细代码样例:
#include <bits/stdc++.h>
using namespace std;
//说白了 构造一个连通子图 只有子图足够大时 才能够判断是犯罪团伙
int N,K,minute[2001] = {0},visited[2001] = {0};//minute是通话次数
unordered_map<string,int> M1;//实现字符与编号的转换
unordered_map<int,string> M2;//为了找距离
vector <int> v[2001];//保证连接关系
struct gang{//构成有成员 有头领 有通话总时间
vector<int>member;
string head;
int totaltime;
};//团伙结构体
gang g[2001];
int num_of_gang = 0;
void dfs(int cur){
if(visited[cur]) return;//及时止损
visited[cur]=1;//遍历过后标记
g[num_of_gang].member.emplace_back(cur);//把这个点加进去
g[num_of_gang].totaltime+=minute[cur];//当前这个团队的总时间
for(int each:v[cur]){//然后开始遍历与这个点有关的所有节点 来构建一张连通子图
dfs(each);
}
}
//因为团队要按照首领的字母大小排序
bool comp(gang x,gang y){
return x.head<y.head;
}
int main(){
int i,j,k,l;
cin>>N>>K;
for(i=0;i<N;i++){
string s1,s2;
cin>>s1>>s2>>l;
//字符串不方便定位,转为数字
if(M1.count(s1)) j = M1[s1];//如果M1有这个名字 那么把这个人的代号拿出来 给以后的通话次数+1
else{
j = M1[s1] = M1.size()+1;//如果没有的话 就新开一个编号 原有的尺寸+1
M2[j] = s1;//M2就是实现数字转换到字符串
}
//下面是第二个人
if(M1.count(s2)) k = M1[s2];
else{
k=M1[s2] = M1.size()+1;
M2[k] = s2;
}
minute[j]+=l;//该行的j编号的通话次数
minute[k]+=l;//改行的k编号的通话次数
v[j].emplace_back(k);//j与k相互连接咯
v[k].emplace_back(j);
}
for(i=0;i<=M1.size();i++){//开始遍历连通子图 每个点都遍历 然后遍历过的就不遍历啦 看看有多少个连通子图 每个子图是否满足gang 如果满足就记录下来咯
if(!visited[i]){//该点未遍历过
g[num_of_gang].member.clear();//gang的初始化
g[num_of_gang].totaltime=0;//时间初始化 这些是不是不用吧 不是的 嘿嘿嘿 这个还必须要 因为 可能if压根就不满足 那个这个团队其实是废了的 重新要做一个团队 这个还蛮坑的
dfs(i);
//开始处理连通子图里面的点
if(g[num_of_gang].member.size()>2&&g[num_of_gang].totaltime>K*2){//首先要满足连通子图的点大于两个人 且时间大于规定时间
//开始确定首领的头
int maxminute = 0;
int head;
//遍历连通子图的每一个点所有的时间
for(int each:g[num_of_gang].member){//找团队首领
if(minute[each]>maxminute){//找到通话次数最多的那个 首领就找到了
maxminute = minute[each];
head=each;
}
}
g[num_of_gang].head=M2[head];//把首领的字符串给到这个团队编号
num_of_gang++;//团队编号进入下一个
}
}
}
//gang排序
sort(g,g+num_of_gang,comp);
//输出团队有多少个
cout<<num_of_gang<<endl;
//每个团队的具体信息 比如 头领 成员有多少
for(i=0;i<num_of_gang;i++){
cout<<g[i].head<<' '<<g[i].member.size()<<endl;
}
}