kruskal:
typedef pair<int, int> pii;
const int N = 600 + 10, M = 2000000 + 10, INF = 0x3f3f3f3f;
struct edge
{
int v, u, cost;
friend bool operator< (edge a, edge b)
{
return a.cost < b.cost;
}
}g[N*N];
int cnt;
int par[N], rnk[N];
void init(int n)
{
cnt = 0;//初始化边集
for(int i = 1; i <= n; i++) par[i] = i, rnk[i] = 0;
}
int ser(int x)
{
int r = x, i = x, j;
while(r != par[r]) r = par[r];
while(par[i] != r) j = par[i], par[i] = r, i = j;
return r;
}
void unite(int x, int y)
{
x = ser(x), y = ser(y);
if(x == y) return;
if(rnk[x] > rnk[y]) par[y] = x;
else
{
par[x] = y;
if(rnk[x] == rnk[y]) rnk[y]++;
}
}
bool same(int x, int y)
{
return ser(x) == ser(y);
}
void add_edge(int v, int u, int cost)
{
cnt++;
g[cnt].v = v, g[cnt].u = u, g[cnt].cost = cost;
}
int kruskal(int n)
{
int tot = 0, ans = 0;
sort(g + 1, g + 1 + cnt);
for(int i = 1; i <= cnt; i++)
{
if(! same(g[i].v, g[i].u))
{
unite(g[i].v, g[i].u);
ans += g[i].cost;
tot++;
}
}
return tot == n-1 ? ans : -1; //选中的边数不到n-1,说明无生成树
}
prim:
typedef pair<int, int> pii;
const int N = 600 + 10, M = 2000000 + 10, INF = 0x3f3f3f3f;
int g[N][N]; //邻接矩阵存图
int mincost[N];
bool vis[N];
int prim(int n)
{//点下标1~n
memset(mincost, 0x3f, sizeof mincost);
memset(vis, 0, sizeof vis);
mincost[1] = 0;
int ans = 0, tot = 0;
while(true)
{
int v = -1;
for(int i = 1; i <= n; i++)
if(! vis[i] && (v == -1 || mincost[i] < mincost[v])) v = i;
if(v == -1 || mincost[v] == INF) break;
vis[v] = true;
ans += mincost[v];
tot++;
for(int i = 1; i <= n; i++) mincost[i] = min(mincost[i], g[v][i]);
}
return tot == n ? ans : -1;//选中的点数不到n,说明无生成树
}
二叉堆优化prim:
typedef pair<int, int> pii;
const int N = 600 + 10, M = 2000000 + 10, INF = 0x3f3f3f3f;
struct edge
{
int to, cost, next;
}g[N*N*2];
int cnt, head[N];
int mincost[N];
bool vis[N];
void init()
{
cnt = 0;
memset(head, -1, sizeof head);
}
void add_edge(int v, int u, int cost)
{
g[cnt].to = u, g[cnt].cost = cost, g[cnt].next = head[v], head[v] = cnt++;
}
int prim(int n)
{//点下标1~n
priority_queue<pii, vector<pii>, greater<pii> > que;
memset(vis, 0, sizeof vis);
memset(mincost, 0x3f, sizeof mincost);
que.push(pii(0, 1)), mincost[1] = 0;
int ans = 0, tot = 0;
while(! que.empty())
{
int v = que.top().second; que.pop();
if(vis[v]) continue;
vis[v] = true;
tot++;
ans += mincost[v];
for(int i = head[v]; i != -1; i = g[i].next)
{
int u = g[i].to;
if(mincost[u] > g[i].cost)
{
mincost[u] = g[i].cost;
que.push(pii(mincost[u], u));
}
}
}
return tot == n ? ans : -1;//选中的点数不到n,说明无生成树
}