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 threthold, 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 59AAA BBB 10BBB AAA 20AAA CCC 40DDD EEE 5EEE DDD 70FFF GGG 30GGG HHH 20HHH FFF 10Sample Output 1:2AAA 3GGG 3Sample Input 2:8 70AAA BBB 10BBB AAA 20AAA CCC 40DDD EEE 5EEE DDD 70FFF GGG 30GGG HHH 20HHH FFF 10Sample Output 2:0/*#include<iostream>#include<cstdio>#include<vector>#include<string>#include<set>#include<algorithm>using namespace std;const int maxn = 26 * 26 * 26;set<int> V;int String2Int(string s){ int sum = 0; for (int i = 0; i < 3; i++) { sum += (s[2-i] - 'A')*pow(26, i); } return sum;}string Int2String(int hash){ string s = "AAA"; for (int i = 0; i < 3; i++) { s[2-i] += hash % 26; hash /= 26; } return s;}int G[maxn][maxn] = { 0 };bool vis[maxn] = { false };int gangmembers = 0;int personaltotalweight[maxn] = { 0 };int totalweight = 0;int maxtotalweight = 0;int head_gangmembers[maxn] = { 0 };int head;int N, K;vector<int> heads;void DFS(int u){ vis[u] = true; gangmembers++; if (maxtotalweight <= personaltotalweight[u]) { maxtotalweight = personaltotalweight[u]; head = u; } for (set<int>::iterator it = V.begin(); it!=V.end();it++) { if (G[u][*it]>0)//这里一定要注意无向图的特性,若存储还是按有向图存储, //那么对无向图遍历时则注意使相邻点只满足弱连通即可 { totalweight += G[u][*it]; G[u][*it] = G[*it][u] = 0;//防止回头 if(!vis[*it]) DFS(*it); } //personaltotalweight[u] += G[u][*it] + G[*it][u];//统计时也要注意是否能放在if语句内 }}void DFSTrave(){ for (set<int>::iterator it = V.begin(); it != V.end(); it++) { gangmembers = 0; totalweight = 0; maxtotalweight = 0;//这样的重置条件不能轻易放在if语句中 if (!vis[*it]) { DFS(*it); if (gangmembers > 2 && totalweight > K) { heads.push_back(head); head_gangmembers[head] = gangmembers; } } }}int main(){ scanf("%d %d", &N, &K); string s1, s2; int weight; for (int i = 0; i < N; i++) { cin >> s1 >> s2 >> weight; int i1 = String2Int(s1); int i2 = String2Int(s2); G[i1][i2] += weight;//注意两个相同的人可能不止是一次AAA BBB 10,下一个还可能是AAA BBB 20 G[i2][i1] += weight; personaltotalweight[i1] += weight; personaltotalweight[i2] += weight; V.insert(i1); V.insert(i2); } DFSTrave(); cout << heads.size()<<endl; for (int i = 0; i < heads.size(); i++) { cout << Int2String(heads[i]) << " " << head_gangmembers[heads[i]] << endl; } return 0;}*//*这题不知道为什么,调了一晚上还调不好,就剩2号测试点过不了。最开始自己写就是2号过不了然后对照别人AC的代码改还是AC不了,不知道为啥。可能我用set的缘故,因为其他人都没用set但我自己又感觉问题应该不是出现在set上。唉,DEBUG折寿啊,脑壳痛╭(╯^╰)╮。下面贴上别人ac的代码*/#include<iostream>#include<string>#include<map>#include<vector>using namespace std;const int M = 26 * 26 * 26; //结点最大数目vector<int> v[M]; //图的邻接表表示vector<int> node; //存储遍历的起点int visited[M] = { 0 };int w[M] = { 0 }; //存储每个人的通话时长int n, k; //k是阈值int cnt = 0;//达标的帮派数目int pnum; //一个帮派的成员数int maxtime;//成员中的最大通话时长int headtime;//头目通话时长int headId;//头目idint toId(string &s);//字符串名字转换为数字编号string toName(int x);//编号转换为名字,用于输出void dfs(int start);//dfs算法int main(){ //freopen("in.txt", "r", stdin); cin >> n >> k; for (int i = 0; i < n; i++)//读入数据,同时转换成数字编号 { string s1, s2; int wgt; cin >> s1 >> s2 >> wgt; int d1 = toId(s1); int d2 = toId(s2); v[d1].push_back(d2); v[d2].push_back(d1); w[d1] += wgt; w[d2] += wgt; node.push_back(d1);//稀疏边,存储遍历的起点。这样不需要从0一个个遍历了 } map<string, int> h_map;//利用map的有序性,存储头目信息 vector<int>::iterator it; for (it = node.begin(); it < node.end(); it++) { pnum = 0; maxtime = 0; headtime = 0; if (visited[*it] == 0) dfs(*it); if (pnum > 2 && maxtime > 2 * k)//判断是否符合条件的帮派 { cnt++; string name = toName(headId); h_map[name] = pnum; } } cout << cnt << endl;//输出 if (cnt != 0) { map<string, int>::iterator it; for (it = h_map.begin(); it != h_map.end(); it++) cout << it->first << ' ' << it->second << endl; } return 0;}int toId(string &s)//字符串名字转换为数字编号{ return ((s[0] - 'A') * 26 * 26 + (s[1] - 'A') * 26 + (s[2] - 'A'));}string toName(int x)//编号转换为名字,用于输出{ string s(3, 0); s[2] = x % 26 + 'A'; s[1] = x / 26 % 26 + 'A'; s[0] = x / 26 / 26 + 'A'; return s;}void dfs(int start)//dfs算法, 里面用到的变量为便于遍历,都设为全局变量{ visited[start] = 1; pnum++; maxtime += w[start]; if (w[start] > headtime)//更新头目信息 { headtime = w[start]; headId = start; } for (unsigned i = 0; i < v[start].size(); i++)//dfs遍历邻接点 { if (visited[v[start][i]] == 0) dfs(v[start][i]); } return;}
新闻热点
疑难解答