题目类型:MST
题意:n个点给出邻接矩阵(对称),求MST。
算法:kruscal,prime。
kruscal,边操作,每次选最短边,如果两边连接的点不在同一集合,加入可用边,一直到n-1条为止。
优化:并查集的优化,priority_queue(或者预处理)
kruscal代码:(边少点多)
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
#define N 150
#define ffor(i, n) for(i=0; i<n; ++i)
struct node{
int x, y, v;
bool operator < (const node & tmp)
{ return v<tmp.v; }
};
int mat[N][N], fat[N], n;
vector<node> edge;
int find(int x){
if(fat[x]==x) return x;
else {
fat[x]=find(fat[x]);
return fat[x];
}
}
void bing(int x, int y){
fat[find(y)]=find(x);
}
int main()
{
node tmp;
int i, j, x, ans;
while(~scanf("%d", &n)){
ffor(i, n) ffor(j, n) scanf("%d", &mat[i][j]);
edge.clear();
ffor(i, n) ffor(j, i) { tmp.x=j; tmp.y=i; tmp.v=mat[i][j]; edge.push_back(tmp); }
sort(edge.begin(), edge.end());
ffor(i, N) fat[i]=i;
x=1; ans=0;
ffor(i, N*N) {
if(x==n) break;
tmp=edge[i];
if(find(tmp.x)!=find(tmp.y)){
x++;
bing(tmp.x, tmp.y);
ans+=tmp.v;
}
}
printf("%d\n", ans);
}
return 0;
}
9549269 | 1258 | Accepted | 376K | 16MS | C++ | 975B | 2011-11-10 21:05:43 |
prime, 点操作每次扩展用当前最短边扩展未加入集合的点,直到加入所有点。
优化,最短边的堆优化。
prime代码:边多点少
#include <stdio.h>
#define N 150
#define ffor(i, n) for(i=0; i<n; ++i)
const int inf=0x7fffffff;
int mat[N][N], lowc[N], vis[N];
int n;
int prim()
{
int i, j, p, res, minc;
for(i=1; i<n; ++i){
vis[i]=0;
lowc[i]=mat[0][i];
}
vis[0]=1; res=0;
for(i=1; i<n; ++i) {
minc=inf; p=-1;
for(j=1; j<n; ++j) {
if(!vis[j] && minc>lowc[j]){
p=j; minc=lowc[j];
}
}
if(minc==inf) return -1;
res+=minc; vis[p]=1;
for(j=1; j<n; ++j) {
if(!vis[j] && lowc[j]>mat[p][j]){
lowc[j]=mat[p][j];
}
}
}
return res;
}
int main()
{
int i, j;
while(~scanf("%d", &n)){
ffor(i, n) ffor(j, n) mat[i][j]=inf;
ffor(i, n) ffor(j, n) scanf("%d", &mat[i][j]);
printf("%d\n", prim());
}
return 0;
}
9549364 | 1258 | Accepted | 228K | 16MS | C++ | 930B | 2011-11-10 21:25:09 |