思路:最小生成树 + 并查集
分析:简单的最小生成树的题目,直接上模板即可。或直接并查集
/*法一:*/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
#define MAXN 1010
int n , m;
int father[MAXN];/*存储节点的父亲节点*/
int rank[MAXN];/*存储根节点的儿子节点的个数*/
struct Edge{
int x;
int y;
}e[MAXN];
/*并查集的初始化*/
void init_Set(){
for(int i = 0 ; i < MAXN ; i++){
father[i] = i;
rank[i] = 0;
}
}
/*递归查找*/
int Find_Set(int x){
if(father[x] != x)
father[x] = find_Set(father[x]);
return father[x];
}
/*集合的合并*/
void Union(int root_x ,int root_y){
if(rank[root_x] > rank[root_y])
father[root_y] = root_x;
else{
if(rank[root_x] == rank[root_y])
rank[root_y]++;
father[root_x] = root_y;
}
}
void solve(){
int ans = 0;
init_Set();/*初始化并查集*/
for(int i = 0 ; i < m ; i++){
int root_x = Find_Set(e[i].x);
int root_y = Find_Set(e[i].y);
if(root_x != root_y){
ans++;
Union(root_x , root_y);
}
}
printf("%d\n" , n-1-ans);
}
int main(){
while(scanf("%d%d" , &n , &m) , n){
for(int i = 0 ; i < m ; i++)
scanf("%d%d" , &e[i].x , &e[i].y);
solve();
}
return 0;
}
/*法二:*/
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 0xFFFFFFF
#define MAXN 1010
int G[MAXN][MAXN];
int lowcost[MAXN];
int vis[MAXN];
int n , m , ans;
/*Prime算法的模板*/
void Prime(){
int pos , min;
ans = 0;
memset(vis , 0 , sizeof(vis));/*初始化为0*/
vis[1] = 1;/*第一个点标记为1*/
for(int i = 1 ; i <= n ; i++)/*初始化lowcost数组*/
lowcost[i] = G[1][i];
for(int i = 1 ; i <= n ; i++){/*枚举n个顶点*/
min = INF;/*初始化为INF*/
for(int j = 1 ; j <= n ; j++){/*找到最小权边对应顶点*/
if(!vis[j] && min > lowcost[j]){
min = lowcost[j];
pos = j;
}
}
if(min == INF)/*如果min = INF表示已经不再有点可以加入最小生成树中*/
break;
ans += min;
vis[pos] = 1;/*加入最小生成树中*/
for(int j = 1 ; j <= n ; j++){/*更新可更新边的权值*/
if(!vis[j] && lowcost[j] > G[pos][j])/*更新lowcost*/
lowcost[j] = G[pos][j];
}
}
printf("%d\n" , ans);
}
int main(){
//freopen("input.txt" , "r" , stdin);
int a , b;
while(scanf("%d%d" , &n , &m) , n){
for(int i = 1 ; i <= n ; i++){
for(int j = 1 ; j <= n ; j++)
G[i][j] = 1;
}
for(int i = 0 ; i < m ; i++){
scanf("%d%d" , &a , &b);
G[a][b] = G[b][a] = 0;
}
Prime();
}
return 0;
}