最小生成樹(例子)
阿新 • • 發佈:2019-01-28
N個點M條邊的無向連通圖,每條邊有一個權值,求該圖的最小生成樹。Input #include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
int g[1010][1010];
int b[1010][1010];//鄰接矩陣
int vis[1000];//是在哪
int p[1000];//a到b的權值
int maxx=0x3f3f3f3f;
int l(int n,int m)
{
int i,minn,ans,k,j;
ans=0;
memset(vis,0,sizeof(vis));
memset(p,0,sizeof(p));
vis[1]=1;
for(i=2; i<=n; i++)
p[i]=g[1][i];
for(i=2; i<=n; i++)
{
minn=maxx;
k=-1;
for(j=1; j<=n; j++)
if(vis[j]!=1&&minn>p[j])
{
minn=p[j];
k=j;
}
ans+=minn;
vis[k]=1;
for(j=1; j<=n; j++)
{
if((vis[j]!=1&&p[j]>g[k][j]))
p[j]=g[k][j];
}
}
return ans;
}
int main()
{
int n,m,i,j,a,b,c;
scanf("%d%d",&n,&m);
memset(g,0,sizeof(g));
for(i=1; i<=m; i++)
{
scanf("%d%d%d",&a,&b,&c);
g[a][b]=c;
g[b][a]=c;
}
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
if(g[i][j]==0)
{
g[i][j]=maxx;
g[j][i]=maxx;
}
printf("%d\n",l(n,m));
return 0;
}
第1行:2個數N,M中間用空格分隔,N為點的數量,M為邊的數量。(2 <= N <= 1000, 1 <= M <= 50000) 第2 - M + 1行:每行3個數S E W,分別表示M條邊的2個頂點及權值。(1 <= S, E <= N,1 <= W <= 10000)Output
輸出最小生成樹的所有邊的權值之和。Input示例
9 14 1 2 4 2 3 8 3 4 7 4 5 9 5 6 10 6 7 2 7 8 1 8 9 7 2 8 11 3 9 2 7 9 6 3 6 4 4 6 14 1 8 8Output示例
37
prim演算法
#include <iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
int g[1010][1010];
int b[1010][1010];//鄰接矩陣
int vis[1000];//是在哪
int p[1000];//a到b的權值
int maxx=0x3f3f3f3f;
int l(int n,int m)
{
int i,minn,ans,k,j;
ans=0;
memset(vis,0,sizeof(vis));
memset(p,0,sizeof(p));
vis[1]=1;
for(i=2; i<=n; i++)
p[i]=g[1][i];
for(i=2; i<=n; i++)
{
minn=maxx;
k=-1;
for(j=1; j<=n; j++)
if(vis[j]!=1&&minn>p[j])
{
minn=p[j];
k=j;
}
ans+=minn;
vis[k]=1;
for(j=1; j<=n; j++)
{
if((vis[j]!=1&&p[j]>g[k][j]))
p[j]=g[k][j];
}
}
return ans;
}
int main()
{
int n,m,i,j,a,b,c;
scanf("%d%d",&n,&m);
memset(g,0,sizeof(g));
for(i=1; i<=m; i++)
{
scanf("%d%d%d",&a,&b,&c);
g[a][b]=c;
g[b][a]=c;
}
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
if(g[i][j]==0)
{
g[i][j]=maxx;
g[j][i]=maxx;
}
printf("%d\n",l(n,m));
return 0;
}