hdu1102(最小生成树)

戏子无情 提交于 2020-03-26 07:53:27

 题意为将所有点连起来,但是有些边已经帮你连好了,要求你将剩下的连起来形成最小生成树。

 因为一些点已经连起来了,所以应该选用kruskal算法。虽然这道题的图是按照邻接矩阵给出的,但选用prim算法的话,实现起来反而不容易还容易出错,倒不如自己对输入进行一些加工,然后选取kruskal算法。

#include <iostream>
#include <stdio.h>
#include <queue>
using namespace std;
int input[105][105];
int N;
int parent[105];
struct Edge
{
    int s,e,w;
    Edge(int ss,int ee,int ww):s(ss),e(ee),w(ww){}
    Edge(){}
    bool friend operator<(Edge n1,Edge n2)
    {
        return n1.w>n2.w;
    }
};
int findP(int x)
{
    if(x==parent[x])
        return x;
    else
        return parent[x]=findP(parent[x]);
}
void Union(int x,int y)
{
    int xp=findP(x),yp=findP(y);
    parent[yp]=xp;
}
void kruskal()
{
    int ans=0;
    priority_queue<Edge> Q;
    for(int i=1;i<=N;i++)
    {
        for(int j=i+1;j<=N;j++)
        {
            Q.push(Edge(i,j,input[i][j]));
        }
    }
    while(!Q.empty())
    {
        Edge now=Q.top();
        Q.pop();
        if(findP(now.s)!=findP(now.e))
        {
            ans+=now.w;
            Union(now.s,now.e);
        }
    }
    cout<<ans<<endl;
}
int main()
{
    int t,a,b;
    while(~scanf("%d",&N))
    {
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=N;j++)
            {
                scanf("%d",&input[i][j]);
            }
            parent[i]=i;
        }
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&a,&b);
            Union(a,b);
        }
        kruskal();
    }
    return 0;
}

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!