POJ T1287 Networking
题解:
给的最大点数是50,边可能有无数条(这不是明摆着唬人吗......)
数据范围较小,Prim和Kruskal都可以用
Kruskal写法
#include<cstdio>
#include<algorithm>
#define maxn 55
using namespace std;
int n,m,sum,cnt;
int f[maxn];
struct Edge{
int u,v,c;
}edge[maxn*maxn];
bool cmp(Edge a,Edge b){
return a.c < b.c;
}
void init(){
cnt = 0;
for(int i = 1; i <= n ; i++)
f[i] = i;
}
int getf(int x){
return f[x] == x ? x : f[x] = getf(f[x]);
}
bool merge(int u,int v){
int rootu = getf(u);
int rootv = getf(v);
if(rootu != rootv){
f[rootv] = rootu;
return true;
}
return false;
}
void Kruskal(){
sort(edge,edge+m,cmp);
for(int i = 0 ; i < m; i++){
if(merge(edge[i].u,edge[i].v)){
sum += edge[i].c;
cnt++;
}
if(cnt == n-1) break;
}
}
int main(){
int u,v,c;
while(~scanf("%d",&n),n){
scanf("%d",&m);
sum = 0;
if(m){
init();
for(int i = 0; i < m ; i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c);
Kruskal();
}
printf("%d\n",sum);
}
return 0;
}
Prim写法
#include<cstdio>
#include<algorithm>
#define maxn 55
#define INF 0x3f3f3f3f
using namespace std;
int n,m,sum,dis[maxn];
int map[maxn][maxn];
bool vis[maxn];
void init(){
for(int i = 1; i <= n ; i++){
dis[i] = INF;
vis[i] = false;
for(int j = 1; j <= i; j++)
i == j ? map[i][j] = 0 : map[i][j] = map[j][i] = INF;
}
}
void Prim(int s){
dis[s] = 0;
for(int i = 1; i <= n ; i++){
int p = 0, minn = INF;
for(int j = 1; j <= n; j++){
if(!vis[j] && minn > dis[j]){
p = j;
minn = dis[j];
}
}
vis[p] = true;
sum += dis[p];
for(int j = 1; j <= n ; j++){
if(!vis[j] && dis[j] > map[p][j])
dis[j] = map[p][j];
}
}
}
int main(){
int u,v,c;
while(scanf("%d",&n),n){
scanf("%d",&m);
sum = 0;
if(m){
init();
while(m--){
scanf("%d%d%d",&u,&v,&c);
map[u][v] = min(c,map[u][v]);
map[v][u] = map[u][v];
}
Prim(1);
}
printf("%d\n",sum);
}
return 0;
}