题目:
输入输出样例:
input:
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
output:
7
注:
re的两大原因:
1.部分变量没开成全局变量
2.数组越界
代码:
Kruskal算法:
应该说是一种暴力吧,将边按照权值排序,然后按顺序选取,如果选取后会形成环则舍弃这条边,直到变成树,即边数=节点数-1
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#define maxn 211111
using namespace std;
int n,m,x,y,z;
int fa[maxn];
struct edge
{
int x,y,z;
bool operator<(const edge &e1)const
{
return z<e1.z;
}
}e[maxn];
int getfa(int x)
{
return (x==fa[x])?x:(fa[x]=getfa(fa[x]));
}
void merge(int x,int y)
{
int xx=getfa(x),yy=getfa(y);
if (xx==yy) return;
fa[xx]=yy;
}
int main()
{
cin>>n>>m;
int ans=0,cnt=0;
for (int i=1;i<=n;i++) fa[i]=i;
for(int i=1;i<=m;i++) cin>>e[i].x>>e[i].y>>e[i].z;
//cout<<"!!!"<<endl;
//for(int i=1;i<=m;i++) cout<<e[i].x<<" "<<e[i].y<<" "<<e[i].z<<endl;
sort(e+1,e+m+1);
//cout<<"???"<<endl;
//for(int i=1;i<=m;i++) cout<<e[i].x<<" "<<e[i].y<<" "<<e[i].z<<endl;
for(int i=1;i<=m;i++)
{
//cout<<e[i].x<<e[i].y<<e[i].z<<endl;
if(getfa(e[i].x)!=getfa(e[i].y))
{
//cout<<e[i].x<<" "<<e[i].y<<" "<<e[i].z<<" "<<"ans="<<ans;
merge(e[i].x,e[i].y);
ans+=e[i].z;
cnt++;
//cout<<" "<<"ans="<<ans<<endl;
}
if(cnt==n-1) break;
}
if(cnt!=n-1) cout<<"orz"<<endl;
else cout<<ans<<endl;
return 0;
}
prim算法:
随机选取一个作为起点,在与她相连的点中选取权值最小的点
需要注意,题目中给出的数据是存在自环和重边的
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#define maxn 5111
using namespace std;
int n,m,x,y,z;
int ans=0;
int a[maxn][maxn],lowcost[maxn],adjvex[maxn];
int main()
{
cin>>n>>m;
memset(a,0x3f,sizeof(a));
for(int i=1;i<=n;i++) a[i][i]=0;
for(int i=1;i<=m;i++)
{
cin>>x>>y>>z;
a[x][y]=min(a[x][y],z);
a[y][x]=min(a[y][x],z);
}
memset(lowcost,0x3f,(n+1)*sizeof(int));
for(int i=1;i<=n;i++)
{
if(a[1][i])
{
lowcost[i]=a[1][i];
adjvex[i]=1;
}
}
lowcost[1]=0;//表示1已经用过了
for(int i=1;i<=n;i++)
{
int minn=0x3f3f3f3f;
int temp=0;
//for(int j=1;j<=n;j++) cout<<lowcost[j]<<" ";
//cout<<endl;
for(int j=1;j<=n;j++)
{
if(lowcost[j]!=0&&lowcost[j]<minn)
{
temp=j;
minn=lowcost[j];//找到相连的最小权值的点
//cout<<"min="<<minn<<endl;
}
}
if(temp!=0) ans+=minn;
//cout<<"ans="<<ans<<endl;
lowcost[temp]=0;
//cout<<"temp"<<temp<<endl;
//for(int j=1;j<=n;j++) cout<<a[temp][j]<<" ";
//cout<<endl;
for(int j=1;j<=n;j++)
{
if(a[temp][j]!=0&&a[temp][j]<lowcost[j])
{
lowcost[j]=a[temp][j];
adjvex[j]=temp;
}
}
}
int flag=0;
for(int i=1;i<=n;i++)
{
if(lowcost[i]) flag=1;
}//判断是否联通
if(flag) cout<<"orz"<<endl;
else cout<<ans<<endl;
return 0;
}