poj1251

来源:互联网 发布:mac版utorrent 编辑:程序博客网 时间:2024/06/16 01:01

链接:http://poj.org/problem?id=1251

题目大意:首先给你一个图,需要你求出最小生成树,输入N个节点,用大写字母表示了节点,然后节点与节点之间有权值。

比如有9个节点,然后接下来有n-1行表示了边的情况,拿第一行举例
A 2 B 12 I 25
表示A有两个邻点,B和I,AB权值是12,AI权值是25

解题思路:一个很直接的模板题,分别用prim和kruskal实现

prim:

#include <iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<string.h>using namespace std;#define maxn 105#define inf 0x3f3f3f3fint n,m;int maps[maxn][maxn];bool vis[maxn];int  dis[maxn];void prim(){memset(vis,false,sizeof vis);vis[0]=1;for(int i=1;i<n;i++)dis[i]=maps[0][i];dis[0]=0;int sum=0;for(int i=1;i<=n;i++){int pos=-1;for(int j=0;j<n;j++){if(!vis[j]&&(pos==-1||dis[j]<dis[pos]))pos=j;}vis[pos]=true;sum+=dis[pos];for(int j=0;j<n;j++){if(!vis[j]&&dis[j]>maps[pos][j])dis[j]=maps[pos][j];}}printf("%d\n",sum);}int main(){while(~scanf("%d",&n),n!=0){char str1[5];char str2[5];for(int i=0;i<n;i++)for(int j=0;j<n;j++)                if(i==j)                    maps[i][j]=0;                else                    maps[i][j]=inf;for(int i=1;i<=n-1;i++){scanf("%s",str1);scanf("%d",&m);while(m--){scanf("%s",str2);scanf("%d",&maps[str1[0]-'A'][str2[0]-'A']);maps[str2[0]-'A'][str1[0]-'A']=maps[str1[0]-'A'][str2[0]-'A'];}}prim();}return 0;}

kruskal:

#include <iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>#include<string.h>using namespace std;#define maxn 1000int n,m,t;int u[maxn],v[maxn];int  w[maxn];int r[maxn],pre[maxn];int find(int x){int r=x;while(r!=pre[r])r=pre[r];int i=x,j;while(i!=r){j=pre[i];pre[i]=r;i=j;}return r;}void join (int x,int y){int fx=find(x),fy=find(y);if(fx!=fy)pre[fx]=fy;}bool cmp(int i,int j){return w[i]<w[j];}int tot;bool check(){int ans=find(1);for(int i=2;i<=n;i++)if(find(i)!=ans)return false;return true;}void kruskal(){int t=0;for(int i=0;i<n;i++)pre[i]=i;for(int i=0;i<tot;i++)r[i]=i;sort(r,r+tot,cmp);int  sum=0;for(int i=0;i<tot;i++){int e=r[i],x=find(u[e]),y=find(v[e]);if(x!=y){sum+=w[e];pre[x]=y;}if(check())break;}printf("%d\n",sum);}int main(){while(~scanf("%d",&n),n!=0){tot=0;char str1[5];char str2[5];int a,b;for(int i=1;i<=n-1;i++){scanf("%s",str1);scanf("%d",&a);while(a--){scanf("%s",str2);scanf("%d",&b);u[tot]=str2[0]-'A';v[tot]=str1[0]-'A';w[tot]=b;tot++;}}kruskal();}return 0;}