poj 1251 最小生成树基础

来源:互联网 发布:nginx error log 关闭 编辑:程序博客网 时间:2024/05/24 01:57

题目:点击打开链接

题意:


分析:

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


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;}




0 0
原创粉丝点击