POJ - 2421 Constructing Roads

Title description:

Given a complete graph of n vertices, find the minimum spanning tree of the graph, in which some edges must be selected.

Among them, the minimum spanning tree represents the tree with the smallest edge weight sum in the graph.

input Output:

insert image description here
insert image description here

enter output
3 179
0 990 692
692 179 0
1
1 2

Ideas:

This question is relatively short, and the content is not a difficult question type. The summary is a template question of the minimum spanning tree.
This problem is a directed weighted graph. But the difficulty of this question is "some sides must". This is still a dying struggle. For this problem, we have two solutions;
1. Directly add the edges that must be stored to the queue after the input is completed.
2. After adding to the queue, the edge weight can be cleared to 0.
Both methods can be done, just choose what you like, I choose the first method.
For the first method, some students may wonder if I add it in the first time and make sure it will not be added in the second time?
The data range of this question is small, and kurskal can be used to type directly, and kruskal has an operation to judge that two nodes are using a subtree. When traversing these edges in the second pass, he will find that these edges have been stored in If it is in the minimum spanning tree, then skip to query other edges.

AC code implementation:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int N=10005;
int father[N],g[N][N];//g数组是邻接矩阵的输入数组
struct Node
{
    
    
	int u,v,w;
	Node(){
    
    };
	Node(int u,int v,int w):u(u),v(v),w(w){
    
    };
	bool operator < (const Node &x) const
	{
    
    
		return w<x.w;
	}
};
vector<Node> e;
int Find(int x)
{
    
    
	return father[x]==x?x:father[x]=Find(father[x]);
}
void Union(int u,int v)
{
    
    
	u=Find(u),v=Find(v);
	if(u!=v) father[u]=v;
}
int kruskal(int n)
{
    
    
	int k=0,ans=0;
	for(int i=0;i<e.size();i++)
	{
    
    
		int u=e[i].u,v=e[i].v,w=e[i].w;
		if(Find(u)!=Find(v))
		{
    
    
			Union(u,v);
			ans+=w;
			if(++k==n-1) break;
		}
	}
	return ans;
}
void init()
{
    
    
	e.clear();
	for(int i=0;i<N;i++)
	{
    
    
		father[i]=i;
	}
}
void solve()
{
    
    
	init();
	int n,q;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
		for(int j=1;j<=n;j++)
		{
    
    
			cin>>g[i][j];
			if(i!=j)
			{
    
    
				e.push_back(Node(i,j,g[i][j]));
			}
		}
	}
	sort(e.begin(),e.end());
	cin>>q;
	for(int i=0;i<q;i++)
	{
    
    
		int u,v;
		cin>>u>>v;
		Union(u,v);
	}
	cout<<kruskal(n)<<endl;
}
int main()
{
    
    
	solve();
	return 0;
}

Summary: The small difficulty of this question lies in the processing and storage operations of the necessary edges. The rest is kruskal's fundamentals.
It's not easy to create, please don't go whoring for nothing www! Please give the author a like + triple bah, thank you!

Guess you like

Origin blog.csdn.net/2301_76331300/article/details/131844285