思路:最小生成树 + 并查集
分析:简单的最小生成树的题目,直接上模板即可。或直接并查集
/*法一:*/ #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; }