当前位置: 首页 > 编程日记 > 正文

1034 Head of a Gang(图的DFS解法) 擦边大法好

1.题目的大意是给出很多人(结点)之间的通话记录,每两人之间的权重取决于他俩通话权重的总时长,如果一个社区的人数超过2且社区内发生的通话总时长超过给定阈值,那么这属于一个社区。最后要求输出社区的总数,再按照社区头目的姓名字母序从小到大输出头目姓名和社区人数。

2. DFS的注意点,这是我第一次写图的DFS。根据教材给的总结出需要两个函数:DFS(int no,int socNo)DFStraver(),由后者调用前者,至于参数是根据实际情况决定的。配套还要有一个布尔数组vis[maxn]来记录每一个点是否被访问过。

3.vis[maxn]的修改发生在DFS(int no,int socNo)内部,第一句话就是。被用到是在DFStraver()的进入搜索之前。一般来说在DFS(int no,int socNo)的内部,开始遍历当前节点的所有邻接结点时,一是要判断是不是邻接结点,而是要判断该邻接节点是否被访问过。但是本题我起初这么做的时候,发现第三个社区就没有被当作社区,输出权重才发现该社区的总权重被算出是50。如图所示

why?一定是FFF和HHH之间的那条边没算进权重,究其原因,该社区的进入结点是FFF,第二个是GGG,第三个是HHH,但是当HHH开始遍历其子节点的时候,会发现唯一的子节点FFF(GGG和HHH之间的边已经被擦除)被访问过了。所以FFF和HHH之间那条边自然也就不会但算进去。怎么解决呢?自然是要把遍历子节点前判断是否已经访问过的条件给删掉。

void DFS(int no,int socNo){//传入人的编号和社区编号 vis[no] = true;//处理社区头目问题 int headNo = social[socNo].head;if(wper[no]>wper[headNo])social[socNo].head = no;//处理社区人数问题social[socNo].pers.insert(no);for(int i=0;i<totalNum;i++){if(adj[no][i]!=0){//处理社区权重问题social[socNo].totalWei += adj[no][i];//擦掉加入过的这条边adj[no][i] = adj[i][no] = 0; DFS(i,socNo);}} 
}void DFStraver(){for(int i=0;i<totalNum;i++){if(vis[i]==false){DFS(i,socNum);if(social[socNum].pers.size()>2&&social[socNum].totalWei>thre)validNum++;socNum++;}}
}

4.  但是当我删掉,新的问题来了,这样FFF这个结点会被算作两次,导致社区三的节点总数被记作了4。于是我想到集合的去重功能,不再在社区结构体设置人数这一变量,而是设置set<int>来记录编号,调用size()函数得到人数。

struct Social{int head = maxn;//社区的头头set<int> pers;//人的编号 int totalWei = 0;//总权重 
}social[maxn];

5. 在记入一条边的权重后,记得将这条边删除(我也是看参考书才知道),但是注意了这是无向图,邻接矩阵中的两个相互对称的位置都记录了这条边,所以抹零两个数。

6. 下面的三剑客是方便将string和int互相映射,不是哈希那种哦,注意学习

map<string,int> strToIntMp;//姓名从字符串映射到编号map<int,string> intToStrMp;//姓名从编号映射到字符串int archive(string s){if(strToIntMp.find(s)!=strToIntMp.end())return strToIntMp[s];//说明这个人已经存档过了//如果没有,要先确定他是第几号 int num = strToIntMp.size();//两个映射集是同步的 strToIntMp[s] = num;intToStrMp[num] = s;return num; 
} 

7. 急性子与慢性子

最后唠叨一点细枝末节。可以让代码结构更清晰。

急性子:由于是每个社区权重最大的那个人做头头,所以开了一个int数组,存放每个人的权重,这个和邻接矩阵一样,一边读入一边就该加上了。

int wper[maxn] = {0};//每个人的权重
for(int i=0;i<n;i++){cin>>p1>>p2>>ct;no1 = archive(p1);no2 = archive(p2);wper[no1] += ct;wper[no2] += ct;adj[no1][no2] += ct; adj[no2][no1] += ct;
}

慢性子:我一开始没注意到要输出真正的社区(达到了那两条要求)的个数,想着设置一个统计总的社区个数的全局变量socNum就好了,最后排好序再把不合格的给过滤掉。但是亡羊补牢也为时未晚,再设置一个统计真正的社区数的全局变量validNum,这个也在DFStraver()中,每次结束一个新社区的遍历后更新。可以见得,过滤放最后也没关系。

void DFStraver(){for(int i=0;i<totalNum;i++){if(vis[i]==false){DFS(i,socNum);if(social[socNum].pers.size()>2&&social[socNum].totalWei>thre)validNum++;socNum++;}}
}

AC代码

#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<cmath>
typedef long long LL;using namespace std;const int maxn = 2010;int wper[maxn] = {0};//每个人的权重bool vis[maxn] = {false};//是否被遍历到 int adj[maxn][maxn] = {0};//邻接矩阵(本题是无向图) map<string,int> strToIntMp;//姓名从字符串映射到编号map<int,string> intToStrMp;//姓名从编号映射到字符串int archive(string s){if(strToIntMp.find(s)!=strToIntMp.end())return strToIntMp[s];//说明这个人已经存档过了//如果没有,要先确定他是第几号 int num = strToIntMp.size();//两个映射集是同步的 strToIntMp[s] = num;intToStrMp[num] = s;return num; 
} int n,thre;//call-num,threshold
int totalNum;//总人数 struct Social{int head = maxn;//社区的头头set<int> pers;//人的编号 int totalWei = 0;//总权重 
}social[maxn];int socNum = 0;//社区个数 
int validNum = 0;//有效社区数 void DFS(int no,int socNo){//传入人的编号和社区编号 vis[no] = true;//处理社区头目问题 int headNo = social[socNo].head;if(wper[no]>wper[headNo])social[socNo].head = no;//处理社区人数问题social[socNo].pers.insert(no);for(int i=0;i<totalNum;i++){if(adj[no][i]!=0){//处理社区权重问题social[socNo].totalWei += adj[no][i];//擦掉加入过的这条边adj[no][i] = adj[i][no] = 0; DFS(i,socNo);}} 
}void DFStraver(){for(int i=0;i<totalNum;i++){if(vis[i]==false){DFS(i,socNum);if(social[socNum].pers.size()>2&&social[socNum].totalWei>thre)validNum++;socNum++;}}
}bool cmp(Social a,Social b){return intToStrMp[a.head]<intToStrMp[b.head];
} int main(){scanf("%d %d",&n,&thre);string p1,p2;//person1 person2int no1,no2;//上面两个人的编号 int ct;//call timefor(int i=0;i<n;i++){cin>>p1>>p2>>ct;no1 = archive(p1);no2 = archive(p2);wper[no1] += ct;wper[no2] += ct;adj[no1][no2] += ct; adj[no2][no1] += ct;}//进行深度优先搜索totalNum = strToIntMp.size();//总人数DFStraver();sort(social,social+socNum,cmp);//按照头头的姓名字母序从小到大排序 //输出有效社区总数 printf("%d\n",validNum);for(int i=0;i<socNum;i++){if(social[i].pers.size()>2&&social[i].totalWei>thre){cout<<intToStrMp[social[i].head];printf(" %d\n",social[i].pers.size());} } return 0;
}

相关文章:

Android定位方式和测试方法

Android常用的三种定位方式有&#xff1a;基于GPS定位、基于基站地位、基于wifi定位。 1、基于GPS定位&#xff1a; GPS定位需要GPS模块(硬件)的支持,没有GPS模块是无法进行GPS定位的。 GPS定位最大的优点就是其定位精确度高(一般误差在10m内),无网络也能用;缺点就是耗电高、定…

vue el-form鼠标事件导致页面刷新解决方案;vue 阻止多次点击提交数据通用方法...

一.阻止表单自动提交刷新页面&#xff1a;<el-form><el-form-item :inline"true" submit.native.prevent><el-input keyup.enter.nativesubmit></el-input></el-form-item> </el-form>注意&#xff1a; 鼠标事件导致页面刷新问…

[转]wxODBC(wxWidgets)中使用驱动程序方式打开数据库

wxODBC(wxWidgets)中使用驱动程序方式打开数据库 wxWidgets的文档中都是使用在控制面板/数据源中设定DSN来创建ODBC连接。但是实际上很多小型的应用&#xff0c;只是使用本机的一个Access数据库。而要求使用者学习ODBC的DSN配置明显的增加了软件的使用难度。因此&#xff0c;研…

1076 Forwards on Weibo

1. 这题说的是&#xff0c;微博上人们之间有关注和被关注的关系&#xff0c;如果一个人发博&#xff0c;他的追随者就可能转发&#xff0c;追随者的追随者又可能转发&#xff0c;以此类推。现在给定一个人&#xff0c;求其微博可能被转发的人数&#xff0c;但是注意有一个关注链…

2014年个人工作总结

2014年的日常工作&#xff0c;从技术支持岗位调到市场.社区岗位上&#xff1a;日常技术处理工作变为博客、微信、微博、市场活动策划、发送奖品等。如果以此为界&#xff1a;即毕业10年内的主要是软件研发、团队管理、项目管理&#xff1b;第二个十年开始&#xff0c;有幸从事市…

DAL(数据库访问层)

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Data;using System.Data.SqlClient;using System.Configuration; /// <summary>///DBHelper 的摘要说明/// </summary>public static class DBHelper{ public …

Navicat for Oracle

1、先解压Navicat for Oracle到任意目录 2、将instantclient-basic-nt-12.1.0.2.0解压到1中目录的instantclient_10_2文件夹下&#xff08;推荐&#xff0c;可随意&#xff09; 3、将instantclient-sqlplus-nt-12.1.0.2.0解压到instantclient_10_2文件夹中的 instantclient_12_…

1013 Battle Over Cities(图的DFS解法)

这题的背景是战争年代&#xff0c;假如城市1被占领&#xff0c;那么所有和城市1相关的公路都要被炸毁&#xff0c;但是这样一来&#xff0c;2和3就不连通了&#xff0c;所以需要补修一条23之间的公路。但是换做城市2或3被占领&#xff0c;1和另一座城市是联通的&#xff0c;并不…

你必须了解的微服务架构设计的10个要点!

近来&#xff0c;几乎人人都在谈论微服务。微服务之所以火热也是因为相对之前的应用开发方式有很多优点&#xff0c;如更灵活、更能适应现在需求快速变更的大环境等。本文将介绍微服务架构设计中的一些要点。 微服务架构设计时有哪些要点呢&#xff1f;先看下图是 Spring Cloud…

企业信息化中常见决策点应对

我和一位朋友在聊天的时候&#xff0c;谈起在甲方的做信息化&#xff0c;和在乙方做信息化的不同点在于&#xff0c;在甲方做信息化&#xff0c;需要搞定为什么要上一个项目。而乙方参与进来的时候&#xff0c;项目其实已经启动了。 是的&#xff0c;作为甲方的我们&#xff0c…

WebView调试

https://developer.chrome.com/devtools/docs/remote-debugging 转载于:https://www.cnblogs.com/daishuguang/p/4194882.html

1013 Battle Over Cities(并查集解法)

关于背景的介绍见1013 Battle Over Cities(图的DFS解法) DFS就是不算特定结点后数连通子图的总数&#xff0c;再减一。我想着那么并查集就是数不算特定节点后&#xff0c;集合元素(根)的个数。但是我弄错了一件事&#xff0c;我是边输入&#xff0c;边合并&#xff0c;然后对于…

FastDFS为什么要结合Nginx?

为什么选择Nginx Nginx 是一个很牛的高性能Web和反向代理服务器, 它具有有很多非常优越的特性: 在高连接并发的情况下&#xff0c;Nginx是Apache服务器不错的替代品: Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一. 能够支持高达 50,000 个并发连接数的响应, 感谢…

STL容器[34]

SERVER以读打开FIFO&#xff1b;CLIENT以写打开FIFO&#xff1b;SERVER关闭FIFO&#xff1b;CLIENT向当前FIFO写数据&#xff0c;此时CLIENT获得一个SIGPIPE信号。如果忽略该信号&#xff0c;那么write将返回-1&#xff0c;ERRNO为EPIPE向一个写打开&#xff0c;当对端已经关闭…

企业可视化报表工具选型经验分享

选型背景 我们是一家面向金融行业的系统集成商&#xff0c;每年要做十几个项目&#xff08;看得出来我们并不大/笑哭&#xff09;&#xff0c;项目分大小、做事分先后&#xff0c;可不管怎样都绕不开数据&#xff0c;数据处理经常占项目的大头&#xff0c;所以经常会选择一些市…

1003 Emergency(Dijkstra,Bellman-Ford,SPFA三种解法)

目录 1. Dijkstra解法 2. Bellman-Ford解法 3. SPFA解法 4. Dijkstra解法AC代码 5. Bellman-Ford解法AC代码 6. SPFA解法AC代码 1. Dijkstra解法 这题不仅涉及到基础的解法&#xff0c;还涉及到第二标准(累计军队数量)&#xff0c;以及还要记录最短路径条数。这些都是在…

存储过程4-前台

代码 ALTERproc[dbo].[P_CheckCode](retintoutput,nIdint,tagnvarchar(50),cCodenvarchar(50),nHotelIdint)asbeginifUpper(tag)B_AREAbeginifexists(select1fromB_Area wherecCodecCodeandnHotelIdnHotelIdandnId<>nId) setret1elsesetret-1endelseifUpper(t…

安卓学习-其他-文件读写

在android中的文件放在不同位置&#xff0c;它们的读取方式也有一些不同。 本文对android中对资源文件的读取、数据区文件的读取、SD卡文件的读取及RandomAccessFile的方式和方法进行了整理。供参考。 一、资源文件的读取&#xff1a; 1) 从resource的raw中读取文件数据&#x…

X5同层播放器应用实践

移动端浏览器中的video元素是比较特别的&#xff0c;早期无论是在iOS还是Android的浏览器中&#xff0c;它都位于页面的最顶层&#xff0c;无法被遮挡。后来&#xff0c;这个问题在iOS下得到了解决。但是对Android的大部分浏览器来说&#xff0c;问题仍然存在。X5是腾讯基于Web…

1007 Maximum Subsequence Sum(两种思路)

1.解法1 思路 对于动态规划来说&#xff0c;最关键的就是找到状态转移方程&#xff0c;本题设置一个前向数组&#xff0c;元素predp[i]表示的是以元素i结尾的连续数列和的最大值&#xff0c;转移方程是predp[i] max(predp[i-1]a[i],a[i])。要做的事就是完成这个dp数组&#x…

C#学习-EF在三层中使用

1.搭建普通三层 DAL层&#xff0c;BLL层&#xff0c;Model层&#xff0c;Web层&#xff1b; DAL层引用Model层 BLL层引用DAL层和Model层 Web层引用BLL层和Model层 2.实现EF三层的搭建&#xff08;添加引用&#xff0c;修改配置信息&#xff09; 2.1添加EF对象 在Model中添加一个…

各大IT公司笔试真题汇总开发人员一定要加入收藏夹的网站(收藏)

巨人网络java笔试基础题分享 http://www.coderarea.net/bbs/read.php?tid834 百度笔试题 http://www.coderarea.net/bbs/read.php?tid811 百度2010校招运维部门笔试 http://www.coderarea.net/bbs/read.php?tid779 百度2010年校园招聘软件测试笔试题 http://www.coderarea.n…

Python编写Hive UDF

2019独角兽企业重金招聘Python工程师标准>>> 1. 目的 从string类型的字段中解析并汇总每种category类型的总amount 2. 素材 表名&#xff1a;test_table order_no hotel_seq discount_detail D8662EF4E 10212527 NULL 45C024849 …

1045 Favorite Color Stripe(LIS解法)

解题思路 本题属于Longest Increasing Sequence最长不下降子序列&#xff0c;但是要注意&#xff0c;LIS当中不会有无效的元素&#xff0c;而本题是有的&#xff0c;所以先要把无效元素过滤掉&#xff0c;才能转化成为LIS问题。 这里用到了hashTable(用map更慢)&#xff0c;初…

5.8fork父子进程

实验4-2&#xff1a;fork父子进程 实验目的&#xff1a; 理解fork创建子进程的本质 实验要求&#xff1a; 1、按如下要求编写程序: &#xff08;1&#xff09;、打开一个有内容的文件; &#xff08;2&#xff09;、调用fork创建子进程; &#xff08;3&#xff09;、读文件…

word表格自动编号

选中全部内容--右键--项目符号和编号--自定义--编号样式--选01,02样式.则生成所有编号选中第二批编号,--重新编号,就又从01开始了转载于:https://www.cnblogs.com/wzshhynk/archive/2009/12/30/1635805.html

Vue API(directives) 自定义指令

前言&#xff1a;除了vue的内置指令以外&#xff0c;我们可以定义自定义指令。内置指令表相见&#xff1a;https://www.cnblogs.com/ilovexiaoming/p/6840383.html 我们定义一个最简单的 <script> export default {name: App,data(){return{yanse:red}},// 所有自定义指令…

1045 Favorite Color Stripe(LCS解法) 需再理解

解题思路 使用LCS方法解这一题&#xff0c;首先要把现有的颜色和Eva的颜色看成即将取材的序列s和e。 而且注意2个序列都要从1开始读入&#xff0c;因为递归边界&#xff08;待后叙&#xff09;。 dp[i][j]代表的是e[1]-e[i]和s[1]-s[j]的范围内&#xff0c;公共子序列的长度…

C++ primer第五版随笔--2015年1月6日

记录自己看这本书时的一些内容。 一、引用&#xff08;reference&#xff09; 引用为对象起了另外一个名字。例如&#xff1a; int ival1024&#xff1b; int &relVal1ival;//对&#xff0c;注意尽量不要用这方式&#xff1a;int& relvalival&#xff1b; int &rel…

Python性能分析指南——中

程序使用了多少内存&#xff1f;现在我们对计时有了较好的理解&#xff0c;那么让我们继续弄清楚程序使用了多少内存。我们很幸运&#xff0c;Fabian Pedregosa模仿Robert Kern的line_profiler实现了一个不错的内存分析器。首先使用pip安装:这里建议安装psutil包&#xff0c;因…