4

HDU1233 还是畅通工程(最小生成树)

 3 years ago
source link: https://arminli.com/hdu1233/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

HDU1233 还是畅通工程(最小生成树)

March 30, 2016

题目链接

今天正式开始搞图论了。

MST 裸题,prim 搞的。

#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 110;
bool vis[MAXN];
int lowc[MAXN];
int cost[MAXN][MAXN];
int Prim(int cost[][MAXN], int n){
    int ans = 0;
    memset(vis, false, sizeof(vis));
    vis[0] = true;
    for(int i = 1; i < n; i++)
        lowc[i] = cost[0][i];
    for(int i = 1; i < n; i++){
        int minc = INF;
        int p = -1;
        for(int j = 0; j < n; j++){
            if(!vis[j] && minc>lowc[j]){
                minc = lowc[j];
                p = j;
            }
        }
        if(minc == INF) return -1;
        ans += minc;
        vis[p] = true;
        for(int j = 0; j < n; j++){
            if(!vis[j] && lowc[j]>cost[p][j])
                lowc[j] = cost[p][j];
        }

    }
    return ans;
}

int main(){
//    freopen("a.txt", "r", stdin);
    int n;
    while(scanf("%d", &n) && n){
        memset(cost, 0x3f, sizeof(cost));
        int a, b, c;
        for(int i = 1; i <= n*(n-1)/2; i++){
            scanf("%d %d %d", &a, &b, &c);
            a--; b--;
            cost[a][b] = cost[b][a] = c;
        }
        cout << Prim(cost, n) << endl;
    }
    return 0;
}

Kruskal:

#include<cstring>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;

const int MAXN = 110;   //最大点数
const int MAXM = 10000; //最大边数
int F[MAXN];    //并查集使用
struct Edge{
    int u, v, w;
}edge[MAXM];    //存储边的信息,包括起点/终点/权值
int tol;    //边数,加边前赋值为0
void addedge(int u,int v,int w){
    edge[tol].u = u;
    edge[tol].v = v;
    edge[tol++].w = w;
}
bool cmp(Edge a,Edge b){//排序函数,讲边按照权值从小到大排序
    return a.w < b.w;
}
int findfa(int x){
    if(F[x] == -1)return x;
    else return F[x] = findfa(F[x]);
}
int Kruskal(int n){ //传入点数,返回最小生成树的权值,如果不连通返回-1
    memset(F, -1, sizeof(F));
    sort(edge, edge+tol, cmp);
    int cnt = 0;//计算加入的边数
    int ans = 0;
    for(int i = 0; i < tol; i++){
        int u = edge[i].u;
        int v = edge[i].v;
        int w = edge[i].w;
        int t1 = findfa(u);
        int t2 = findfa(v);
        if(t1 != t2){
            ans += w;
            F[t1] = t2;
            cnt++;
        }
        if(cnt == n-1)break;
}
    if(cnt < n-1)return -1;//不连通
    else return ans;
}


int main(){
    //freopen("a.txt", "r", stdin);
    int n;
    while(~scanf("%d", &n) && n){
        int k = n*(n-1)/2;
        for(tol = 0; tol < k; ){
            int a, b, c;
            scanf("%d %d %d", &a, &b, &c);
            addedge(a, b, c);
        }
        cout << Kruskal(n) << endl;
    }
    return 0;
}




About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK