思路:
- 最小生成树裸题,稠密图,比较一下 Prim & Kruskal …
- Prim:不需要离线做存储边,使用邻接矩阵存储边权即可,用到 Q(NODE)、dis[]、vis[] 。注意初始化、对角线、对称性、单边性。
- Kruskal:记住是并查集就很好写。
代码:
for(int i=1;i<=N;i++)
if(!vis[i] && dis[i] > mp[id][i]){
dis[i] = mp[id][i];
Q.push(NODE(i , dis[i]));
}
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 105;
int N,M;
int ans;
int dis[maxn];
bool vis[maxn];
int mp[maxn][maxn];
struct NODE{
int id;
int dis;
friend bool operator > (NODE a , NODE b)
{
return a.dis > b.dis;
}
NODE(int id,int dis) : id(id) , dis(dis) {} ;
};
priority_queue<NODE , vector<NODE> , greater<NODE> > Q;
void INIT(){
ans = 0;
memset(dis , INF , sizeof(dis));
memset(vis , 0 , sizeof(vis));
memset(mp , INF , sizeof(mp));
for(int i=0;i<maxn;i++)
mp[i][i] = 0;
return ;
}
void PRIM(){
Q.push(NODE(1,0)) ; dis[1] = 0;
while(Q.size()){
NODE cur = Q.top() ; Q.pop();
int id = cur.id ;
if(vis[id])
continue;
vis[id] = true;
ans += dis[id];
for(int i=1;i<=N;i++)
if(!vis[i] && dis[i] > mp[id][i]){
dis[i] = mp[id][i];
Q.push(NODE(i , dis[i]));
}
}
return ;
}
int main(){
while(cin>>N && N){
INIT();
M = N*(N-1)/2;
while(M--){
int l,r,w;
cin>>l>>r>>w;
mp[l][r] = mp[r][l] = min(mp[l][r] , w);
}
PRIM();
cout<<ans<<endl;
}
return 0;
}
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 105;
int N,M;
int ans;
int par[maxn];
struct EDGE{
int l,r,w;
friend bool operator < (EDGE a , EDGE b)
{
return a.w < b.w;
}
}edge[maxn*maxn/2];
void ADDEDGE(int i,int l,int r,int w){
edge[i].l = l;
edge[i].r = r;
edge[i].w = w;
return ;
}
void INIT(){
ans = 0;
memset(par , -1 , sizeof(par));
return ;
}
int FIND(int i){
return par[i] == -1 ? i : par[i] = FIND(par[i]) ;
}
void UNION(int l,int r){
int parl = FIND(l);
int parr = FIND(r);
par[parr] = parl;
return ;
}
void KRUSKAL(){
for(int i=0;i<M;i++){
int l = edge[i].l;
int r = edge[i].r;
int parl = FIND(l);
int parr = FIND(r);
if(parl != parr){
UNION(l,r);
ans += edge[i].w;
}
}
return ;
}
int main(){
while(cin>>N && N){
INIT();
M = N*(N-1)/2;
for(int i=0;i<M;i++){
int l,r,w;
cin>>l>>r>>w;
ADDEDGE(i,l,r,w);
}
sort(edge , edge+M);
KRUSKAL();
cout<<ans<<endl;
}
return 0;
}