Constructing Roads POJ - 2421(最小生成树)详解注释

题目链接
有N个村庄,从1到N,你应该修建一些道路,这样每两个村庄就可以连接起来。我们说两个村庄A和B相连,当且仅当A和B之间有一条路,或者存在一个村庄C使得A和C之间有一条路,并且C和B相连。我们知道一些村庄之间已经有一些道路了,你的工作是修建一些道路,这样所有的村庄都连接起来,所有道路的长度都是最小的。
Input
第一行是整数N (3 <= N <= 100),即村庄数。然后是N行,第i行包含N个整数,第j列是村i和村j之间的距离(距离应该是[1,1000]内的整数)。然后是整数Q (0 <= Q <= N * (N + 1) / 2),然后是Q行,每一行包含两个整数a和b (1 <= a < b <= N),这意味着a村和b村之间的道路已经建成。
Output
您应该输出一条包含整数的线,该整数是所有要修建的道路的长度,以便所有村庄都连接起来,并且该值是最小的。
Sample Input
3
0 990 692
990 0 179
692 179 0
1
1 2
Sample Output
179

详见代码:


```cpp
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define inf 0x3f3f3f3f
//const int inf=0x3f3f3f3f;
int n;
int mp[105][105],dis[105];
//int vis[105];
bool vis[105];//0为false,1为true。
void Prim()
{
    int v,mi;
	/*for(int i=2;i<=n;i++)
    {
		dis[i]=mp[1][i];
		//vis[i]=1;
		vis[i]=false;
	}*/
	for(int i=1;i<=n;i++)
    {
        dis[i]=mp[1][i];//先把1加入Vnew,若给出1到与1相连的点,则dis就是给出的输入的mp[1][i],否则就是inf
        vis[i]=false;
    }
	//vis[1]=0;
	//vis[1]=true;
	//dis[1]=0;
	int sum=0;
	//for(int i=1;i<=n-1;i++)
    for(int i=1;i<=n;i++)
	{
	    mi=inf;
		for(int j=1;j<=n;j++)
		    //if(mi>dis[j]&&vis[j]!=0)
            if(!vis[j]&&mi>dis[j])//在集合V中先找出一个没有加入集合Vnew的&&权值最小的点
            {
                mi=dis[j];
                v=j;//v先后等于1,2,3 
            }
		vis[v]=true;//标记该点已经加入Vnew
		dis[v]=0;//路已经修好,距离更新为0
		sum+=mi;
		for(int j=1;j<=n;j++)
		{
			/*if(dis[j]>dis[v]+mp[v][j])
			{
				dis[j]=dis[v]+mp[v][j];
				vis[j]=v;
			}*/
			if(!vis[j]&&dis[j]>mp[v][j])//如果这个点没有加入Vnew还在V中&&
            {
                dis[j]=mp[v][j];
            }
		}
	}
	printf("%d\n",sum);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	       //mp[i][j]=mp[j][i]=(i==j)?0:inf;
	       {
	           if(i==j)
                mp[i][j]=mp[j][i]=0;
               else
                mp[i][j]=mp[j][i]=inf;
	       }
	for(int i=1;i<=n;i++)
	    for(int j=1;j<=n;j++)
	        scanf("%d",&mp[i][j]);
	int q;
	scanf("%d",&q);
	while(q--)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		mp[a][b]=mp[b][a]=0;
	}
	Prim();
	return 0;
}

跑代码

发布了67 篇原创文章 · 获赞 2 · 访问量 1852

猜你喜欢

转载自blog.csdn.net/weixin_44641254/article/details/104077103