hdu1102 最小生成树

孤者浪人 提交于 2020-03-26 07:52:51

本题本是模板题,但由于开始并查集写出,好不容易发现了,有没改彻底,导致狂WA,以后一定要注意,修改后要多检查,别急忙交;

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#define maxn 105
using namespace std;

const int INF = 0x3f3f3f;
int G[maxn][maxn];
struct Edge{
    int from;
    int to;
    int len;
    bool operator <(const Edge& rh) const {
        return len < rh.len ;
    }
};

struct MST{
    int n;
    int m;  
    Edge edge[maxn*maxn];
    int p[maxn];
    void init(int num){
        m = 0; 
        n = num; 
        for(int i=0;i<n;i++) p[i] = i; 
    }
    int find(int x){
        return p[x]==x ? x : p[x] = find(p[x]);
    }
    void Addedge(int i,int j,int len){
        edge[m].from = i;
        edge[m].to = j;
        edge[m].len = len;
        m++;
    }                      
    int krusal(){
        int ans = 0;  
        sort(edge,edge+m);  
        
        for(int i=0;i<m;i++){
            int x = edge[i].from;
            int y = edge[i].to;;
            int z = edge[i].len;
            if(find(x) != find(y)){
                int a = find(x),b = find(y); //这是刚开始 WA 的原因; 
                p[a] = b;
                ans += z; 
            }
        }
        return ans;
    }
}Slover;
int main(){
    //if(freopen("input.txt","r",stdin)== NULL)  {printf("Error\n"); exit(0);}
    int N;
    while(cin>>N){
        memset(G,0,sizeof(G));
        Slover.init(N);
        for(int i=0;i<N;i++)
         for(int j=0;j<N;j++){
              cin>>G[i][j];
           } 
           for(int i=0;i<N;i++)
          for(int j=i+1;j<N;j++){
               Slover.Addedge(i,j,G[i][j]); 
         }
           int Q;
           cin>>Q;
           for(int i=0;i<Q;i++){
               int a,b;
               cin>>a>>b;
               a--; b--;
               if(Slover.find(a) != Slover.find(b)){
                   int x = Slover.find(a),y = Slover.find(b);
                   Slover.p[x] = y;     //这么改到位
               }
        }
          int ans = Slover.krusal();
        printf("%d\n",ans);
    }
    return 0;
}

 prim算法:

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#define maxn 105
using namespace std;

const int INF = 0x3f3f3f;
int G[maxn][maxn];
int ans;
int n;

void prim(){
    bool vis[maxn];
    int lowdist[maxn];  //每个点的最小相邻边; 
    int mindist;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++) lowdist[i]=INF;
    int point;
    int s=1;
    vis[s] =true;
    int num=1;  
    while(true){
        if(num == n) break;
        vis[s]=true;
        mindist = INF;
        for(int i=1;i<=n;i++){
            if(!vis[i] && lowdist[i] > G[s][i]){
                lowdist[i] = G[s][i];  
            }
            if(!vis[i] && mindist>lowdist[i]){
                mindist=lowdist[i];  
                point = i;  //printf("%d %d %d\n",G[1][2],mindist,i);
            }
        }
        s = point;
        ans += mindist;  
        num++;
    } 
    return;
}

int main(){
    //if(freopen("input.txt","r",stdin)== NULL)  {printf("Error\n"); exit(0);}
    
    while(cin>>n){
        memset(G,0x3f,sizeof(G));
        ans = 0;
        for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++){
              cin>>G[i][j];
           } 
           int Q;
           cin>>Q;
           for(int i=0;i<Q;i++){
               int a,b;
               cin>>a>>b;
               G[a][b] = G[b][a] = 0;
           }
        //print();
           prim();
           printf("%d\n",ans);
    }
           return 0;
}
View Code

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!