例题
其中prim算法(在这里卡了好久关于prim和dij的区别后来才发现他们的主要差别就是点与点之间的距离和点与集合间的距离的差别 )
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 105;
const int inf = 0x3f3f3f3f;
typedef long long ll;
int n;
int map[maxn][maxn];
int v[maxn];
int d[maxn];
int pim(int x)
{
int res=0;
memset(v,0,sizeof(v));
memset(d,inf,sizeof(d));
d[x]=0;
for(int i=1;i<=n;i++){
int minn=-1;
for(int j=1;j<=n;j++){
if(!v[j]){
if(minn==-1||d[minn]>d[j]){
minn=j;
}
}
}
if(d[minn]==inf)break;
v[minn]=1;
res+=d[minn];
for(int j=1;j<=n;j++){
if(!v[j]){
if(d[j]>map[minn][j]){
d[j]=map[minn][j];
}
}
}
}
return res;
}
int main()
{
while(~scanf("%d",&n)){
if(n==0)break;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(i==j)
map[i][j]=0;
else
map[i][j]=inf;
}
}
for(int i=1;i<=n*(n-1)/2;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
map[a][b]=min(map[a][b],c);
map[b][a]=map[a][b];
}
int ans=pim(1);
printf("%d\n",ans);
}
return 0;
}
用邻接表优先队列实现的
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 10005;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int,int>p;
int n,m;
int cnt=0;
int head[maxn],d[maxn],v[maxn];
struct node
{
int y,t,p;
friend bool operator <(node a,node b)
{
return a.t>b.t;
}
}s[maxn<<1];
void add(int n,int m,int k)
{
s[++cnt]=node{m,k,head[n]};
head[n]=cnt;
}
int prim(int x)
{
memset(v,0,sizeof(v));
memset(d,0,sizeof(d));
priority_queue<node>q;
int ans=0;
v[x]=1;
for(int i=head[x];~i;i=s[i].p){
q.push(s[i]);
}
for(int i=1;i<n;i++){
if(q.size()==0)break;
node w=q.top();
q.pop();
if(v[w.y]){
while(v[w.y]){
w=q.top();
q.pop();
}
}
v[w.y]=1;
ans+=w.t;
for(int i=head[w.y];~i;i=s[i].p){
if(!v[s[i].y])
q.push(s[i]);
}
}
return ans;
}
int main()
{
while(~scanf("%d",&n)){
if(n==0)break;
cnt=0;
memset(head,-1,sizeof(head));
for(int i=1;i<=n*(n-1)/2;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
int ans=prim(1);
printf("%d\n",ans);
}
return 0;
}
用Kruskal算法实现:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int maxn = 10005;
const int inf = 0x3f3f3f3f;
typedef long long ll;
struct node
{
int x,y,t;
}s[maxn<<1];
int n,m;
int f[maxn];
int cmp(node a,node b)
{
return a.t<b.t;
}
int find(int x)
{
if(x==f[x])return x;
return f[x]=find(f[x]);
}
void merge(int a,int b)
{
int fa=find(a);
int fb=find(b);
if(fa!=fb){
f[fa]=f[fb];
}
}
int main()
{
while(~scanf("%d",&n)){
if(n==0)break;
for(int i=1;i<=n;i++){
f[i]=i;
}
for(int i=1;i<=n*(n-1)/2;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
s[i].x=a,s[i].y=b,s[i].t=c;
}
int ans=0;
sort(s+1,s+n*(n-1)/2+1,cmp);
for(int i=1;i<=n*(n-1)/2;i++){
int a=s[i].x;
int b=s[i].y;
int fa=find(a);
int fb=find(b);
if(fa!=fb){
merge(a,b);
ans+=s[i].t;
}
}
printf("%d\n",ans);
}
return 0;
}