牛 客 oj Exercice 11.3 || pat1034 Chef d'un gang (avec poids et ensemble de contrôle + carte imbriquée + ensemble)

 

Lien titre: cliquez ici

L'idée principale: Comme indiqué dans le livre des rois, trouvez le chef de gang et son numéro.

Idée: Cette question n'est pas tant qu'une collection, il vaut mieux traiter de la chaîne. Parce que la chaîne d'entrée est convertie au point correspondant, puis définie et vérifiée, puis la chaîne de sortie et le numéro associé sont utilisés, j'ai donc utilisé 3 cartes et 1 jeu. . Il existe également une carte imbriquée, qui est rarement jouée. .

L'idée générale est la suivante:

La partie du jeu de contrôle consiste à fusionner les jeux en fonction de la relation de poids du nœud.
1. Commencez par stocker le bord dans la structure;
2. Ensuite, numérotez les nœuds (les chaînes sont numérotées séquentiellement dans ce cas);
3. Traversez ensuite les bords et modifiez le tableau de poids des nœuds;
4. Fusionnez et mettez à jour le chemin en même temps; (Étant donné que la collection est fusionnée en fonction des poids des nœuds, et non en fonction des poids unilatéraux, la mise à jour de la compression du chemin est requise à la fin)
5. Recherchez le leader dans le tableau père et comptez le nombre de membres;
6. Supprimez les faux leaders et les faux groupes ( Le groupe doit être supérieur à 2 personnes)
7. Sortie.

Puisqu'il n'y a pas de mise à jour de chemin 1W, la prémisse est que Niuke a donné des données de test. . Je ne peux pas finir si calmement après l'examen, hein, hein. .

 

 

 

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <climits>
 
using namespace std;
 
const int MAXN = 2005;
const int INF = INT_MAX;

struct Edge{
	string SourceA;
	string SourceB;
	int value;
};

int N, K;
int father[MAXN], weight[MAXN];
Edge edge[MAXN];

int Find(int x){
	if(x != father[x]) father[x] = Find(father[x]);
	return father[x];
}

void Union(int x, int y){
	x = Find(x);
	y = Find(y);
	if(x != y){
		if(weight[x] < weight[y]) father[x] = y;
		else if(weight[y] < weight[x]) father[y] = x;
		else{//权值相等 
			if(y < x) father[x] = y;
			else if(x < y) father[y] = x;
		}
	}
}

void Initial(){
	for(int i = 0; i < MAXN; i++){
		father[i] = i;
		weight[i] = 0;
	}
}

int main(){
//	freopen("in.txt", "r", stdin);
	while(~scanf("%d %d", &N, &K)){
		Initial();
		set<string> allPoint;//所有字符串点 
		map<string, int> mymap1;//字符串到编号 
		map<int, string> mymap2;//编号到字符串 
		map<int, pair<int, int> > mymap3;//编号到次数 
		for(int i = 0; i < N; i++){
			cin >> edge[i].SourceA;
			cin >> edge[i].SourceB;
			scanf("%d", &edge[i].value);
			allPoint.insert(edge[i].SourceA);
			allPoint.insert(edge[i].SourceB);
		}
		//编号 
		set<string>::iterator it1;
		int count = 0; //count为节点数 
		for(it1 = allPoint.begin(); it1 != allPoint.end(); it1++){
			mymap1[*it1] = count;
			mymap2[count] = *it1; 
			count++;
		}
		//加入边得出权值数组 
		int num1, num2;
		for(int i = 0; i < N; i++){
			num1 = mymap1[edge[i].SourceA];
			num2 = mymap1[edge[i].SourceB];
			weight[num1] += edge[i].value;
			weight[num2] += edge[i].value;
		}
		//对所有边合并 
		for(int i = 0; i < N; i++){
			num1 = mymap1[edge[i].SourceA];
			num2 = mymap1[edge[i].SourceB];
			Union(num1, num2);
		}
		//路径更新 
		for(int i = 0; i < count; i++){
			Find(i);
		}
		//从father数组中找出boss 
		map<int, pair<int, int> >::iterator it2;
		int boss;
		for(int i = 0; i < count; i++){
			boss = father[i];
			it2 = mymap3.find(boss);
			if(it2 != mymap3.end()){
				mymap3[boss].first++;
				mymap3[boss].second += weight[i];
			}
			else{
				mymap3[boss].first = 1;
				mymap3[boss].second = weight[i];
			}
		}
		//消除假boss 
		map<int, pair<int, int> >::iterator it3;
		for(it3  = mymap3.begin(); it3 != mymap3.end(); it3++){
			if(it3->second.first <= 2 || ((it3->second.second / 2) <= K)) mymap3.erase(it3); 
		} 
		//输出 
		printf("%d\n", mymap3.size());
		for(it3  = mymap3.begin(); it3 != mymap3.end(); it3++){
			cout << mymap2[it3->first] << " " << it3->second.first << endl;
		} 
	}
	return 0;
}

 

Publié 411 articles originaux · J'aime 72 · Visites 160 000+

Je suppose que tu aimes

Origine blog.csdn.net/Flynn_curry/article/details/105441791
conseillé
Classement