【PAT】A1034 Head of a Gang (30分)

tech2024-04-19  10

题目

解决

思路

因为结点的最大值不大,所以用邻接矩阵实现图(一般不超过1000个点的时候用邻接矩阵)考虑到名字和编号的映射,用Map实现,所以需要map<string, int> name2id, 和map<int, string> id2name;在DFS的过程中,要计算每个类的大小(人数),这个类里面weight最大的人,这个类的总weight,所以DFS需要以上3个参数和当前访问结点,为了修改这三个参数,传入的应该是地址。注意点: 通话记录最多1000条,所以最多有2000人,而不是1000人。map<type1, type2>是按照type1从小到大排序的,用这个可以解决题目要求的输出按字典序大小递增的要求。numMember初始值为0,因为在DFS的第一个顶点处就++了因为图中可能出现环,为了边权不被漏加,需要先累加边权然后再考虑递归DFS的问题,但是这样做可能会出现重复访问的问题,所以再累加之后将图中对应的两个边置零。

实现

Code1

#include<cstdio> #include<iostream> #include<string> #include<map> using namespace std; const int MAXV = 2010; const int INF = 1000000000; map<string, int> gang; //head->人数 map<string, int> name2id; map<int, string> id2name; int n, k; int numPerson = 0; //总人数 int G[MAXV][MAXV] = {0}; int weight[MAXV] = {0}; //每个人的权重 bool vis[MAXV] = {false}; void DFS(int now, int& head, int& numMember, int& totalWeight){ numMember++; vis[now] = true; if(weight[now] > weight[head]){ head = now; } for(int i=0; i<numPerson; i++){ if(G[now][i] > 0){ totalWeight += G[now][i]; G[now][i] = 0; G[i][now] = 0; if(vis[i] == false){ DFS(i, head, numMember, totalWeight); } } } } void DFSTravel(){ for(int i=0; i<numPerson; i++){ if(vis[i] == false){ int head = i; int numMember = 0; int totalWeight = 0; DFS(i, head, numMember, totalWeight); if(numMember > 2 && totalWeight > k){ // 说明这个是gang gang[id2name[head]] = numMember; } } } } int getId(string str){ if(name2id.find(str) != name2id.end()){ return name2id[str]; }else{ name2id[str] = numPerson; id2name[numPerson] = str; return numPerson++; } } int main(){ scanf("%d%d", &n, &k); string name1, name2; int time; for(int i=0; i<n; i++){ cin >> name1 >> name2 >> time; //每个人增加相应的time int id1 = getId(name1); int id2 = getId(name2); weight[id1] += time; weight[id2] += time; G[id1][id2] += time; G[id2][id1] += time; } DFSTravel(); cout << gang.size() << endl; for(map<string, int>::iterator it=gang.begin(); it!=gang.end(); it++){ cout << it->first << " " << it->second << endl; } }
最新回复(0)