-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path10_A1034.cpp
182 lines (170 loc) · 4.77 KB
/
10_A1034.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/**
* P354 Head of a Gang
* 图的 DFS 遍历
*/
#include <iostream>
#include <vector>
#include <map>
#include <climits>
#include <algorithm>
#define MAXN 1010
using namespace std;
// 用来建立 名字 和 编号 的映射关系
map<string, int> name2num;
map<int, string> num2name;
// 记录 Gang 的数据
// string: head 名字,int: gang 的总人数
map<string, int> gang;
// 记录一个点的权值
map<int, int> vertixWeight;
// 图 邻接矩阵
// 首先初始化为 无穷,无法达到
int graph[MAXN][MAXN] = {INT_MAX};
// 判断是否访问过
int hasVisited[MAXN] = {false};
/**DFS 遍历一个连通块
* current: 当前访问的顶点
* &head: 该连通块点权最大的顶点
* &totalTimeLength: 总边权
* &totalNum: 该连通块的总人数
*/
void DFS(int current, int &head, int &totalTimeLength, int &totalNum)
{
// 访问当前的顶点
totalNum += 1;
// set true
hasVisited[current] = true;
// 是否需要更新 head
if (vertixWeight[current] > vertixWeight[head])
{
head = current;
}
// 遍历 current 的邻接点
for (int i = 0; i < vertixWeight.size(); i++)
{
// 邻接点
// 对称矩阵,不需要遍历已经遍历过的
if (graph[current][i] < INT_MAX && i > current)
{
totalTimeLength += graph[current][i];
// 如果没有访问过
if (!hasVisited[i])
{
DFS(i, head, totalTimeLength, totalNum);
}
}
}
}
/**DFS 遍历连通块
* count: 全体人数
* k: 判断是 Gang 的阈值
*/
void DFSTraverse(int count, int k)
{
for (int i = 0; i < count; i++)
{
// 如果没有访问过
if (hasVisited[i] == false)
{
// 说明是一个新的连通块
int head = i, totalTimeLength = 0, totalNum = 0;
DFS(i, head, totalTimeLength, totalNum);
// 访问完了,通过引用带回了数据
// 判断是否是 Gang
if (totalTimeLength > k && totalNum > count)
{
gang.insert(make_pair(num2name[head], totalNum));
}
}
}
}
// 初始化数据
void init()
{
// num: phone calls number
// k: threthold
int num, k;
int count = 0;
cout << "Input the number of calls and the threthold: ";
cin >> num >> k;
cout << "Input the relations: " << endl;
for (int i = 0; i < num; i++)
{
string name1, name2;
int timeLength;
cin >> name1 >> name2 >> timeLength;
// 判断是否需要添加新的映射
if (name2num.find(name1) == name2num.end())
{
name2num.insert(make_pair(name1, count));
num2name.insert(make_pair(count, name1));
vertixWeight.insert(make_pair(count, 0));
count += 1;
}
if (name2num.find(name2) == name2num.end())
{
name2num.insert(make_pair(name2, count));
num2name.insert(make_pair(count, name2));
vertixWeight.insert(make_pair(count, 0));
count += 1;
}
// 加点权
vertixWeight[name2num[name1]] += timeLength;
vertixWeight[name2num[name2]] += timeLength;
// 加边权
// 如果刚开始这两个点不是邻接的,那么先设置为 0
if (graph[name2num[name1]][name2num[name2]] == INT_MAX)
{
graph[name2num[name1]][name2num[name2]] = 0;
}
if (graph[name2num[name2]][name2num[name1]] == INT_MAX)
{
graph[name2num[name2]][name2num[name1]] = 0;
}
graph[name2num[name1]][name2num[name2]] += timeLength;
graph[name2num[name2]][name2num[name1]] += timeLength;
}
}
// print
void print()
{
cout << "All Gangs' info: " << endl;
for (map<string, int>::iterator it = gang.begin(); it != gang.end(); it++)
{
cout << it->first << " " << it->second << endl;
}
}
// test
void test()
{
cout << "graph: " << endl;
for (int i = 0; i < vertixWeight.size(); i++)
{
for (int j = 0; j < vertixWeight.size(); j++)
{
cout << graph[i][j] << " ";
}
cout << endl;
}
cout << "name2num: " << endl;
for (map<string, int>::iterator it = name2num.begin(); it != name2num.end(); it++)
{
cout << it->first << " " << it->second << endl;
}
cout << "num2name: " << endl;
for (map<int, string>::iterator it = num2name.begin(); it != num2name.end(); it++)
{
cout << it->first << " " << it->second << endl;
}
cout << "vertix weight: " << endl;
for (map<int, int>::iterator it = vertixWeight.begin(); it != vertixWeight.end(); it++)
{
cout << it->first << " " << it->second << endl;
}
}
int main()
{
init();
test();
return 0;
}