poj 1251 最小生成树基础

题目:点击打开链接

题意:


分析:

就是给一个图,求最小生成树。


prime算法:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int N=50;
int g[N][N],dis[N];
char op[2];
int n;
bool vis[N];
int prim(int src)
{
    for(int i=0;i<n;i++){
        dis[i]=g[src][i];
    }
    memset(vis,0,sizeof(vis));
    vis[src]=1;
    int res=0;
    int p;
    for(int i=1;i<n;i++){
        int tmp=0x3f3f3f3f;
        for(int j=0;j<n;j++){
            if(!vis[j]&&dis[j]<tmp){
                tmp=dis[j];
                p=j;
            }
        }
        //if(tmp==0x3f3f3f3f)break;
        res+=tmp;
        vis[p]=1;
        for(int j=0;j<n;j++){
            if(!vis[j]&&dis[j]>g[p][j])dis[j]=g[p][j];
        }
    }
    return res;
}
int main()
{

    while(~scanf("%d",&n)&&n){
        int num,w;
        memset(g,0x3f,sizeof(g));
        for(int i=1;i<n;i++){
            scanf("%s%d",op,&num);
            int u=op[0]-'A';
            while(num--){
                scanf("%s%d",op,&w);
                int v=op[0]-'A';
                if(w<g[u][v])
                g[u][v]=g[v][u]=w;
            }
        }
        printf("%d\n",prim(0));
    }
}

priority_queue优化的prime算法,但是数据有点弱,跟上面都是0ms,没太大区别。

我觉得,这种方法之于prime,就像spfa之于dijkstra,思想都是一致的,只是实现不同而已。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int N=50;
#define MP(x,y) make_pair(x,y)
typedef pair<int,int>pii;
vector<pii>e[N];
bool vis[30];
int dis[30];
int n;
int prim(int src)
{
    priority_queue<pii,vector<pii>,greater<pii> >q;
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    int res=0;
    dis[src]=0;
    q.push(MP(0,src));
    while(!q.empty()){
        pii t=q.top();
        q.pop();
        int u=t.second;
        if(!vis[u]){
            vis[u]=1;
            res+=dis[u];
            for(int i=0;i<e[u].size();i++){
                int v=e[u][i].second;
                int w=e[u][i].first;
                if(!vis[v]&&dis[v]>w){
                    dis[v]=w;
                    q.push(MP(w,v));
                }
            }
        }
    }
    return res;
}
int main()
{
   // freopen("f.txt","r",stdin);
    char op[2];
    while(~scanf("%d",&n)&&n){
        int num,w;
        for(int i=0;i<n;i++)e[i].clear();
        for(int i=1;i<n;i++){
            scanf("%s%d",op,&num);
            int u=op[0]-'A';
            while(num--){
                scanf("%s%d",op,&w);
                int v=op[0]-'A';
                e[u].push_back(MP(w,v)),e[v].push_back(MP(w,u));
            }
        }
        printf("%d\n",prim(0));
    }
    return 0;
}

Kruskal算法:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int N=50;
struct edge
{
    int u,v,w;
    edge(){}
    edge(int u,int v,int w):u(u),v(v),w(w){}
    bool operator < (const edge &a)const{
        return w<a.w;
    }
}e[100];
int fa[N];
int n;
int findfa(int x)
{
    return fa[x]!=x?fa[x]=findfa(fa[x]):x;
}
int Kruskal(int edgenum)
{
    sort(e,e+edgenum);
    for(int i=0;i<n;i++)fa[i]=i;
    int ans=0;
    for(int i=0;i<edgenum;i++){
        int u=findfa(e[i].u),v=findfa(e[i].v);
        if(u!=v){
            fa[u]=v;
            ans+=e[i].w;
        }
    }
    return ans;
}
int main()
{
   // freopen("f.txt","r",stdin);
    char op[2];
    while(~scanf("%d",&n)&&n){
        int num,w;
        int cnt=0;
       // for(int i=0;i<n;i++)e[i].clear();
        for(int i=1;i<n;i++){
            scanf("%s%d",op,&num);
            int u=op[0]-'A';
            while(num--){
                scanf("%s%d",op,&w);
                int v=op[0]-'A';
                e[cnt++]=edge(u,v,w);
            }
        }
        printf("%d\n",Kruskal(cnt));
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值