poj2421,poj2560,poj1789
这些都是一些比较基础的最小生成树的题目,在这里我分别用两种方法来实现--kruskal以及prim(其中prim是建哥写的,kruskal是我写的).
//poj2421 kruskal
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
int n,m;
int a[105][105],d;
int p[105],xa,yb;
int sum,res;
typedef struct Node
{
int value;
int l;
int r;
};
Node edges[105*105];
int find_set(int x)
{
if(x!=p[x])
p[x]=find_set(p[x]);
return p[x];
}
bool cmp(Node e1,Node e2)
{
return e1.value<e2.value;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
p[i]=i;
}
int sym=0,mm=0,m=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&d);
a[i][j]=a[j][i]=d;
}
}
scanf("%d",&mm);
for(int i=0;i<mm;i++)
{
scanf("%d%d",&xa,&yb);
a[xa][yb]=0;
}
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
edges[m].l=i;
edges[m].r=j;
edges[m].value=a[i][j];
m++;
}
}
sort(edges,edges+m,cmp);
for(int i=0;i<m;i++)
{
int fx=find_set(edges[i].l);
int fy=find_set(edges[i].r);
if(fx!=fy)
{
sum+=edges[i].value;
p[fy]=fx;
}
}
printf("%d\n",sum);
return 0;
}
//poj2421 prim
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
int maps[305][305];
bool vis[305];
int dis[305];
int n;
int Prim()
{
memset(vis,false,sizeof(vis));
for(int i=1; i<=n; i++)
dis[i] = INF;
int ans=0;
dis[1] = 0;
for(int i=1; i<=n; i++)
{
int tmp = INF,k=0;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]<tmp)
{
tmp = dis[j];
k=j;
}
}
vis[k] = true;
ans+=tmp;
for(int i=1; i<=n; i++)
{
if(!vis[i]&&dis[i]>maps[k][i])
dis[i] = maps[k][i];
}
}
return ans;
}
int main()
{
while(scanf("%d",&n),n)
{
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=0; i<n-1; i++)
{
int t;
char a[2],b[2];
scanf("%s%d",a,&t);
for(int j=0; j<t; j++)
{
int dist;
scanf("%s%d",b,&dist);
maps[a[0]-'A'+1][b[0]-'A'+1] = maps[b[0]-'A'+1][a[0]-'A'+1] = dist;
}
}
printf("%d\n",Prim());
}
return 0;
}
//poj2560 kruskal
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int t;
typedef struct Node
{
double x;
double y;
};
typedef struct Edge
{
int l;
int r;
double value;
};
Edge edges[105*105];
Node node[105];
int p[105],n;
double sum;
bool cmp(Edge e1,Edge e2)
{
return e1.value<e2.value;
}
int find_set(int x)
{
if(x!=p[x])
p[x]=find_set(p[x]);
return p[x];
}
int main()
{
sum=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&node[i].x,&node[i].y);
p[i]=i;
}
int m=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
double d=sqrt((node[i].x-node[j].x)*(node[i].x-node[j].x)+(node[i].y-node[j].y)*(node[i].y-node[j].y));
edges[m].l=i;
edges[m].r=j;
edges[m++].value=d;
}
}
sort(edges,edges+m,cmp);
/* for(int i=0;i<m;i++)
{
printf("%lf\n",edges[i].value);
}*/
for(int i=0;i<m;i++)
{
int fx=find_set(edges[i].l);
int fy=find_set(edges[i].r);
if(fx!=fy)
{
sum+=edges[i].value;
p[fy]=fx;
}
}
printf("%.2lf\n",sum);
return 0;
}
//poj 2560 prim
#include <stdio.h>
#include <string.h>
#include <math.h>
#define INF 0x3f3f3f3f
int n;
double maps[300][300];
bool vis[300];
double dis[300];
struct Point {
double x;
double y;
}points[300];
double Prim()
{
memset(vis,false,sizeof(vis));
for(int i=1;i<=n;i++)
dis[i] = INF;
dis[1] = 0;
double ans =0;
for(int i=1;i<=n;i++)
{
double tmp = INF;
int k =0;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&dis[j]<tmp)
{
tmp = dis[j];
k= j;
}
}
vis[k]=true;
ans+=tmp;
for(int i=1;i<=n;i++)
{
if(!vis[i]&&dis[i]>maps[k][i])
dis[i] = maps[k][i];
}
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&points[i].x,&points[i].y);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
double x = points[i].x - points[j].x;
double y = points[i].y - points[j].y;
maps[i][j] = sqrt(x*x+y*y);
}
}
printf("%.2lf\n",Prim());
return 0;
}
//poj1789 kruskal
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
char str[2050][10];
int p[2050];
typedef struct Edge
{
int l;
int r;
int value;
};
bool cmp(Edge e1,Edge e2)
{
return e1.value<e2.value;
}
int find_set(int x)
{
if(x!=p[x])
p[x]=find_set(p[x]);
return p[x];
}
Edge edges[2050*2050];
int getDif(int x,int y)
{
int num=0;
for(int i=0;i<7;i++)
{
if(str[x][i]!=str[y][i])
{
num++;
}
}
return num;
}
int main()
{
while(scanf("%d",&n)&&n!=0)
{
memset(edges,0,sizeof(edges));
memset(str,0,sizeof(str));
int m=0;
for(int i=1;i<=n;i++)
{
scanf("%s",str[i]);
p[i]=i;
}
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
int num=getDif(i,j);
edges[m].l=i;
edges[m].r=j;
edges[m++].value=num;
}
}
sort(edges,edges+m,cmp);
int sum=0;
for(int i=0;i<m;i++)
{
int fx=find_set(edges[i].l);
int fy=find_set(edges[i].r);
if(fx!=fy)
{
sum+=edges[i].value;
p[fy]=fx;
}
}
printf("The highest possible quality is 1/%d.\n",sum);
}
return 0;
}
//poj1789 prim
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f3f
int maps[2005][2005];
char str[2005][2005];
int dis[2005];
bool vis[2005];
int n;
int Prim()
{
memset(vis,false,sizeof(vis));
for(int i=1; i<=n; i++)
dis[i] = INF;
int ans=0;
dis[1] = 0;
for(int i=1; i<=n; i++)
{
int tmp = INF,k=0;
for(int j=1; j<=n; j++)
{
if(!vis[j]&&dis[j]<tmp)
{
tmp = dis[j];
k=j;
}
}
vis[k] = true;
ans+=tmp;
for(int i=1; i<=n; i++)
{
if(!vis[i]&&dis[i]>maps[k][i])
dis[i] = maps[k][i];
}
}
return ans;
}
int main()
{
while(scanf("%d",&n),n)
{
for(int i=0;i<n;i++)
scanf("%s",str[i]);
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int dist = 0;
for(int k=0;k<7;k++)
{
if(str[i][k]!=str[j][k])
dist++;
}
maps[i+1][j+1] = dist;
}
}
printf("The highest possible quality is 1/%d.\n",Prim());
}
return 0;
}
本文通过POJ平台上的三道经典题目,详细介绍了两种求解最小生成树(MST)问题的算法:Kruskal算法和Prim算法。每种算法都提供了完整的C/C++代码实现,并对关键步骤进行了注释说明。
684

被折叠的 条评论
为什么被折叠?



