Introduction à l'arbre couvrant minimum (algorithme Prim)

la description

Récemment, un nouveau Mod pour Sim City, un jeu auquel Xiao Hi aime jouer, s'est ouvert. Dans ce Mod, les joueurs peuvent posséder plus d'une ville!

Cependant, les problèmes se sont succédés: Little Hi a maintenant N villes en main et connaît le coût de construction de routes entre deux de ces villes N. Little Hi veut savoir que cela coûtera le moins cher possible. deux villes quelconques peuvent se rejoindre par les routes construites (en supposant qu'il y ait trois villes A, B, C, il suffit de construire des routes entre AB et BC, alors AC peut également passer par ces deux routes connectées).

Indice: je ne sais pas pourquoi l'algorithme de Prim est très similaire à l'algorithme de Dijstra Σ (っ ° Д °;) っ. × Fermer

Astuce: je ne sais pas pourquoi l'algorithme de Prim est très similaire à l'algorithme de Dijstra Σ (っ ° Д °;) っ.

Little Ho a également regardé Little Hi jouer à ce jeu tout le temps, alors il a émis ses propres pensées: "Pourquoi est-ce que ce doit être le moins cher? C'est normal de le faire et de passer le niveau!"

Little Hi a dit avec colère: "Savez-vous ce que signifie le TOC?"

Alors Little Ho s'est tue et n'a pas osé parler.

Little Hi renifla, puis dit: "Aussi, saisissez cette opportunité, je peux vous apprendre ce qu'est le spanning tree minimum - d'abord parler de l'origine du nom, le terme spanning tree est relatif à une certaine image dont G vient, que c'est-à-dire que vous ne pouvez pas dire qu'un arbre T est un arbre couvrant, vous pouvez seulement dire que T est un arbre couvrant de G, et le sens de l'arbre couvrant est que les nœuds de T et G sont les mêmes, et T Le L'ensemble d'arêtes de G est un sous-ensemble de l'ensemble d'arêtes de G, qui est ce qu'on appelle l'arbre couvrant. L'arbre couvrant minimum signifie le plus petit poids d'arête de tous les arbres couvrant de G. "

"Alors il peut y avoir plus d'un arbre couvrant minimum?" A demandé Little Ho.

Little Hi hocha la tête et répondit: "Oui, donc cette question n'a besoin que de sortir la somme des poids d'arête de l'arbre couvrant minimum - ce doit être le seul."

 

Le petit Ho se gratta la tête et dit: "Alors que dois-je faire? Je n'ai aucune idée du tout - si la méthode d'énumération est utilisée, la complexité temporelle est exponentielle, donc je ne peux certainement pas le faire!"

«Écoutez-moi lentement!» Little Hi a dit: « Tout d'abord, je veux prouver une conclusion: pour la ville i (i ≠ 1), si la distance entre i et la ville 1 n'est pas supérieure à toute autre ville j (j ≠ 1) et La distance de la ville 1, alors l'arête (1, i) doit exister dans un certain arbre couvrant minimum. »

"Vous voulez dire que le bord le plus court de la ville 1 doit appartenir à un certain arbre couvrant minimum? Cela semble raisonnable, mais pourquoi?" Demanda Little Ho.

Little Hi hocha la tête: "La preuve est la suivante: pour un arbre couvrant minimum T-si (1, i) est dedans, alors la conclusion a été prouvée, donc nous considérons que (1, i) n'est pas La situation. 1 et Je serai certainement connecté par un certain chemin (parce que c'est un arbre, pas une forêt), supposons que ce soit 1-p1-p2 -...- pk-i. "

"Hmm, alors quoi?"

"Donc, si je supprime le bord (1, p1) et ajoute le bord (1, i), est-ce toujours un arbre couvrant? ", A demandé Little Hi.

"Le point n'a pas changé et l'ensemble d'arêtes est toujours un sous-ensemble du graphe G, il vous suffit donc de voir s'il ne s'agit pas d'un arbre - tous les points sont toujours connectés et il n'y a pas d'anneau (après avoir ajouté l'arête (1, i), il n'y a qu'un seul Anneau 1-p1-p2 -...- pk-i-1, mais (1, p1) a été supprimé)! Donc c'est encore un arbre, c'est-à-dire. .. Après ce changement, c'est toujours un arbre Arbre. »Little Ho réfléchit un moment et dit.

«Si nous appelons l'arbre couvrant modifié T ', il n'est pas difficile de trouver que puisque le coût de (1, p1) est supérieur ou égal au coût de (1, i), nous pouvons savoir que la somme des les poids de bord de T 'sont inférieurs ou égaux à T, et comme T lui-même est déjà un arbre couvrant minimum, il n'est pas difficile de trouver que T'will sera également un arbre couvrant minimum ... "Little Ho a soudainement crié:" C'est-à-dire que la conclusion a été prouvée: (1, i) cette arête doit exister dans un arbre couvrant minimum. "

"D'accord! Donc la première étape de la longue marche est terminée, et il vous suffit de suivre la première étape!" Dit Little Hi.

"Que voulez-vous dire ... la prochaine situation sera beaucoup plus compliquée, non?" Little Ho était perplexe.

Little Hi soupira et dit: "Stupide ... vous pensez que oui, si je suis sûr que l'arête (1, i) doit exister dans un certain arbre couvrant minimum, alors je vais imiter l'idée de l'algorithme de Dijstra et combiner 1 et i Fusionner en un seul point, alors le problème devient de trouver les N-2 points restants et l'arbre couvrant minimum de ce point? Le problème n'a pas changé, mais l'échelle a été réduite, vous n'avez donc besoin de le faire qu'une seule fois. , ce problème n'est-il pas parfaitement résolu? "

Little Ho y réfléchit et dit: "C'est-à-dire ... pour un problème d'arbre couvrant minimum avec N points, je trouve le point i le plus proche du point 1 et fusionne ces deux points, laissant N-1 points., Et puis trouver le point le plus proche du nouveau point 1, fusionner ces deux points, en laissant N-2 points ... et ainsi de suite, jusqu'à ce que le dernier point soit laissé, puis fusionner tous les points précédents Additionner le coût des côtés— c'est la réponse! "

"Russ peut vous apprendre, dépêchez-vous et écrivez le programme! Je l'utiliserai plus tard!"

Fermer

Entrer

Chaque point de test (fichier d'entrée) possède un et un seul ensemble de données de test.

Dans un ensemble de données de test:

La première ligne est un entier N, qui représente le nombre de villes appartenant à Hi.

Les N lignes suivantes sont une matrice N * N A, décrivant le coût de construction de routes entre deux villes quelconques, où le jème nombre de la i-ème rangée est Aij, qui représente la i-ème ville et la j-ème ville. coût de construction de routes entre.

Pour 100% de données, N <= 10 ^ 3 est satisfait, pour tout i, Aii = 0, et pour tout i, j est Aij = Aji, 0 & ltAij & lt10 ^ 4.

Sortir

Pour chaque ensemble de données de test, un entier Ans est sorti, qui représente le coût de construction minimum requis pour que deux villes se rejoignent par les routes construites.

Exemple d'entrée

5
0 1005 6963 392 1182 
1005 0 1599 4213 1451 
6963 1599 0 9780 2789 
392 4213 9780 0 5236 
1182 1451 2789 5236 0 

Exemple de sortie

4178

Idée: algorithme prim

(Je ne comprends pas pourquoi je peux apprendre l'intérêt d'utiliser l'algorithme principal à partir de la question (à l'exclusion de la question): https://blog.csdn.net/with_wine/article/details/113823749 )

Code d'implémentation:

#include<stdio.h>
#include<string.h>
int a[1010][1010],dis[1010],book[1010];
int n,u,min,sum,inf=99999999;/*这个无穷大inf*/ 
int main()
{
	int i,j;
	while(~scanf("%d",&n))
	{
		sum=0;/*我们最后输出的结果*/
		for(i=1;i<=n;i++)
		{
			for(j=1;j<=n;j++)
			{
				scanf("%d",&a[i][j]);
			}
		}
	
		for(i=1;i<=n;i++)
		{
			book[i]=0;
			dis[i]=a[1][i];
		}
		/*修改信息*/
		book[1]=1;
		dis[1]=0;
	
		for(i=1;i<n;i++)
		{
			min=inf;
			for(j=1;j<=n;j++)
			{
				if(book[j]==0&&min>dis[j])
				{
					min=dis[j];
					u=j; 
				}
			}
			/*从标号为1的点出发,找到距离它最近的点,标记*/
			book[u]=1;
			sum+=dis[u];
			for(j=1;j<=n;j++)
			{
				if(book[j]==0&&dis[j]>a[u][j])
				dis[j]=a[u][j];
			} 
		}
		printf("%d\n",sum);
	}
}

Pour approfondir l'impression,    ayons un autre problème d'application de l'algorithme prim: https://blog.csdn.net/with_wine/article/details/113722148 (~  ̄ ▽  ̄) ~ vous êtes le bienvenu

Articles avancés : https://blog.csdn.net/with_wine/article/details/113980197

 

Je suppose que tu aimes

Origine blog.csdn.net/with_wine/article/details/113972924
conseillé
Classement