题目:http://poj.org/problem?id=2377
最大生成树,改一改prim即可,把大小换一换,最初graph都fill为-1。
POJ就好搞一些无聊的重边,要把最大的数据放入graph。
#include<cstdio>
#include<iostream>
#include<queue>
#include<string>
#include<cstring>
#include<map>
using namespace std;
const int maxn=1005;
const int maxcost=999999999;
int graph[maxn][maxn],lowcost[maxn],visit[maxn][maxn];
int prim(int s,int n){
int lowcost[maxn];
int mst[maxn];
int i,j,minn,minid,sum=0;
for(i=1;i<=n;i++){ //lowcost初始化
lowcost[i]=graph[s][i];
mst[i]=s;
}
mst[s]=0;
lowcost[s]=maxcost;
for(i=2;i<=n;i++){
minn=-1;
minid=0;
for(j=1;j<=n;j++){
if(lowcost[j]>minn&&lowcost[j]!=maxcost){
minn=lowcost[j];
minid=j;
}
} //cout<<minn<<endl;
if(minn==-1)
return -1; //不连通
//printf("%c - %c : %d\n", mst[minid] + 'A' - 1, minid + 'A' - 1, min);
sum+=minn;
lowcost[minid]=maxcost;
for(j=1;j<=n;j++){
if(graph[minid][j]>lowcost[j]){
lowcost[j]=graph[minid][j];
mst[j]=minid;
}
}
}
return sum;
}
int main(){
int n,m;
int x,y,val,maxval=0,s=0;
scanf("%d%d",&n,&m);
fill(graph[0],graph[0]+maxn*maxn,-1);
for(int i=0;i<m;i++){
scanf("%d%d%d",&x,&y,&val);
if(val>graph[x][y])
graph[x][y]=graph[y][x]=val;
if(val>maxval){
maxval=val;
s=x;
}
}
printf("%d\n",prim(s,n));
return 0;
}
Kruskal则不需考虑重边,因为find找爸爸判断那里过不去。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=999999999;
int n,m,q,fa[1010];
struct edge{
int x,y,len;
}e[20005];
bool cmp(edge a,edge b){
return a.len>b.len;
}
int find(int x){
return fa[x] != x ? fa[x] = find(fa[x]) : x;
}
int kruskal(){
for(int i=0;i<=n;i++)
fa[i]=i;
sort(e,e+m,cmp);
int cnt=0;
int sum=0;
for(int i=0;i<m;i++){
int x=e[i].x,y=e[i].y;
int t1=find(e[i].x);
int t2=find(e[i].y);
if(t1!=t2){
sum+=e[i].len;
fa[t2]=t1;
cnt++;
}
if(cnt==n-1)
break;
}
if(cnt<n-1)
return -1;
else
return sum;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].len);
printf("%d\n",kruskal());
return 0;
}