最大生成树Kruskal

来源:互联网 发布:斗鱼点播软件 编辑:程序博客网 时间:2024/06/06 16:59


题目大意:Bessie要在John的N个谷仓之间修路,John要求用尽可能少的路使得所有谷仓都能

联通,并且总距离最短,但是他又不想给Bessie钱。Bessie已经意识到John可能不给他钱,所

以他就想把这个工程做的最糟糕并且不让John发现。他决定用尽可能少的路使得所有谷仓都能

联通,但是要使总距离尽可能长。求这个可能的总距离。如果不能使得所有谷仓都联通,则输

出"-1"。

思路:和最小生成树的求法类似,这里使边的权值尽可能大。用Kruskal算法来做,排序的时候,

将边从大到小排序。因为Kruskal算法过程中要先判断两点是否联通,而且边是从大到小排序,所

以如果两点间有重边,则优先选择大的加入生成树中。


#include<iostream>

#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN = 1100;
const int MAXM = 40040;
struct EdgeNode
{
    int from;
    int to;
    int w;
}Edges[MAXM];


int father[MAXN];


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


int cmp(EdgeNode a,EdgeNode b)
{
    return a.w > b.w;
}


void Kruskal(int N,int M)
{
    sort(Edges,Edges+M,cmp);
    int ans = 0,Count = 0;


    for(int i = 0; i < M; ++i)
    {
        int u = find(Edges[i].from);
        int v = find(Edges[i].to);
        if(u != v)
        {
            ans += Edges[i].w;
            father[v] = u;
            Count++;
            if(Count == N-1)
                break;
        }
    }
    if(Count == N-1)
        cout << ans << endl;
    else
        cout << "-1" << endl;
}
int main()
{
    int N,M;
    while(~scanf("%d%d",&N,&M))
    {
        for(int i = 1; i <= N; ++i)
            father[i] = i;
        for(int i = 0; i < M; ++i)
        {
            scanf("%d%d%d",&Edges[i].from, &Edges[i].to, &Edges[i].w);
        }
        Kruskal(N,M);
    }


    return 0;

}



也可以把费用去相反数,然后求最小生成树
#include<iostream>#include<set>#include<map>#include<vector>#include<queue>#include<cmath>#include<climits>#include<cstdio>#include<string>#include<cstring>#include<algorithm>typedef long long LL;using namespace std;const int INF=10000000;int N,M;int col[1005][1005];int dis[1005];bool vis[1005];void prim(){    int ans=0;    int biao;    for(int i=1; i<=N; i++)    {        if(col[1][i]==0)            dis[i]=INF;        else        dis[i]=col[1][i];        vis[i]=false;    }    dis[1]=0;    vis[1]=true;    for(int i=2; i<=N; i++)    {        int min1=INF;        for(int j=2; j<=N; j++)        {            if((!vis[j])&&dis[j]<min1)            {                min1=dis[j];                biao=j;            }        }        ans+=min1;        vis[biao]=true;        for(int j=1; j<=N; j++)            if((!vis[j])&&(col[j][biao]!=0)&&dis[j]>col[j][biao])                dis[j]=col[j][biao];    }    for(int i=1; i<=N; i++)        if(dis[i]>=INF)        {            cout<<-1<<endl;            return;        }    cout<<-ans<<endl;}int main(){    //freopen("in.txt","r",stdin);    int u,v,x;    while(cin>>N>>M)    {        memset(col,0,sizeof(col));        memset(vis,false,sizeof(vis));        for(int i=1; i<=M; i++)        {            cin>>u>>v>>x;            col[u][v]=min(col[u][v],-x);            col[v][u]=col[u][v];        }        prim();    }    return 0;}

0 0
原创粉丝点击