hdu 1232 畅通工程

点击打开链接hdu 1232


思路:最小生成树 + 并查集

分析:简单的最小生成树的题目,直接上模板即可。或直接并查集


/*法一:*/
#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;
}





 


你可能感兴趣的:(hdu 1232 畅通工程)