zoukankan      html  css  js  c++  java
  • [PAT] A1034 Head of a Gang

    (重要!)
    图的DFS遍历;map的使用

    思路

    方法一

    算法笔记第355页

    方法二

    法一中的点权和边权其实是一个东西,用一个map存起来就好,输入的时候如果a和b有通话,则a的点权和b的点权都加上通话时长,且将一条边插入图中(无需知道边长,图用map<string, vector>保存,这样直接以人名对应,比较方便。vector里存的是与键有通话记录的人名,插入时记得遍历一次若无记录才插入,避免重复)。一次DFS遍历得出一个连通图的成员,用vector保存人名,这样顺便也可直接获取人数。连通图各个结点的点值相加再除以二即整个连通图的通话时长总和,这样也避免了遍历图计算边权重复的问题。最后将头目姓名和人数存在一个map中,map会自动排序,直接输出即可。

    AC代码

    方法一

    #define _CRT_SECURE_NO_WARNINGS
    #include<stdio.h>
    #include<iostream>
    #include<string>
    #include<string.h>
    #include<vector>
    #include<map>
    using namespace std;
    #define MAX 2010
    map<string, int>strtoint;
    map<int, string>inttostr;
    map<string, int>gang;
    int G[MAX][MAX] = { 0 };
    int weight[MAX] = { 0 };
    bool vis[MAX] = { false };
    int n, threshold;
    int numPerson = 0;
    void DFS(int now, int& head, int& member, int& total) {
    	vis[now] = true;
    	member++;
    	if (weight[now] > weight[head])
    		head = now;
    	for (int i = 0;i < numPerson;i++) {
    		if (G[now][i] > 0) {
    			total += G[now][i];
    			G[now][i] = G[i][now] = 0;
    			if (vis[i] == false)
    				DFS(i, head, member, total);
    		}
    	}
    }
    void DFSTrave() {
    	int i;
    	for (i = 0;i < numPerson;i++) {
    		if (vis[i] == false) {
    			int head = i, member = 0, total = 0;
    			DFS(i, head, member, total);
    			if (member > 2 && total > threshold) {
    				gang[inttostr[head]] = member;
    			}
    		}
    	}
    }
    int change(string str) {
    	if (strtoint.find(str) != strtoint.end()) {
    		return strtoint[str];
    	}
    	else {
    		strtoint[str] = numPerson;
    		inttostr[numPerson] = str;
    		return numPerson++;
    	}
    }
    int main() {
    	scanf("%d%d", &n, &threshold);
    	int i;
    	for (i = 0;i < n;i++) {
    		string str1, str2;
    		int w;
    		cin >> str1 >> str2 >> w;
    		int id1 = change(str1);
    		int id2 = change(str2);
    		G[id1][id2] += w;
    		G[id2][id1] += w;
    		weight[id1] += w;
    		weight[id2] += w;
    	}
    	DFSTrave();
    	map<string, int>::iterator it;
    	cout << gang.size() << endl;
    	for (it = gang.begin();it != gang.end();it++) {
    		cout << it->first << " " << it->second << endl;
    	}
    	return 0;
    }
    
    

    方法二

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<map>
    #include<vector>
    #include<algorithm>
    using namespace std;
    map<string, int>Gang;//键:头目名;值:人数(满足人数>2,并且通话总时长大于给定值)
    map<string, vector<string>>mp;
    map<string, int>vis;
    vector<string>tmember;//临时存储每个连通图的成员
    map<string, int>headtime;//每个人的通话总时长
    void DFS(string s) {
    	vis[s] = true;
    	tmember.push_back(s);
    	for (int i = 0;i < mp[s].size();i++) 
    		if (vis[mp[s][i]] == false) DFS(mp[s][i]);
    }
    int main() {
    	int i, j, n, time, threshold;
    	string head;
    	scanf("%d%d", &n, &threshold);
    	for (i = 0;i < n;i++) {
    		string name1, name2;
    		cin >> name1 >> name2 >> time;
    		headtime[name1] += time;
    		headtime[name2] += time;
    		vis[name1] = vis[name2] = false;
    		for (j = 0;j < mp[name1].size();j++) 
    			if (mp[name1][j] == name2)
    				break;
    		if (j == mp[name1].size())
    			mp[name1].push_back(name2);
    		for (int j = 0;j < mp[name2].size();j++) 
    			if (mp[name2][j] == name1)
    				break;
    		if (j == mp[name2].size())
    			mp[name2].push_back(name1);
    	}
    	for (auto it = mp.begin();it != mp.end();it++) {
    		if (vis[it->first] == false) {
    			tmember.clear();
    			DFS(it->first);
    			int sumtime = 0;
    			for (i = 0;i < tmember.size();i++)
                                    sumtime += headtime[tmember[i]];
    			sumtime = sumtime / 2;
    			if (sumtime > threshold && tmember.size() > 2) {
    				time = headtime[tmember[0]];
                                    head = tmember[0]; 
    				for (i = 1;i < tmember.size();i++) //找头目:通话多的。
    					if (headtime[tmember[i]] > time) {
    						head = tmember[i];
    						time = headtime[tmember[i]];
    					}
    				Gang[head] = tmember.size();
    			}
    		}
    	}
    	printf("%d
    ", Gang.size());
    	for (auto it = Gang.begin();it != Gang.end();it++)
    		cout << it->first << " " << it->second << endl;
    	return 0;
    }
    
  • 相关阅读:
    DOM--6 向应用程序中加入ajax
    javascript优化--12模式(设计模式)03
    javascript优化--11模式(设计模式)02
    javascript优化--14模式2(DOM和浏览器模式)
    mvc-9测试和调试
    mvc-10部署
    mvc-6依赖管理
    less
    css3 总结03
    css3 总结02
  • 原文地址:https://www.cnblogs.com/yue36/p/12982290.html
Copyright © 2011-2022 走看看