HDU 1233 또는 원활 한 프로젝트 (최소 생 성 트 리 Prime & Kruskal)

Problem 은 한 성에 서 마을 교통 상황 을 조사 하여 얻 은 통계 표 에 임의의 두 마을 간 의 거 리 를 열거 하 였 다.성 정부의 '원활 한 공사' 목 표 는 성 전체의 어느 두 마을 간 에 도 도로 교통 을 실현 할 수 있 도록 하 는 것 이다.가장 작은 도로 의 총 길 이 를 계산 해 주세요.Input 테스트 입력 에는 몇 가지 테스트 용례 가 포함 되 어 있 습 니 다.각 테스트 용례 의 첫 번 째 줄 은 마을 수 N (< 100) 을 드 립 니 다.이 어 N (N - 1) / 2 줄 은 마을 간 의 거리 에 대응 하고 각 줄 은 두 마을 의 번호 와 이 두 마을 간 의 거 리 를 나타 낸다.간단하게 말하자면, 마을 은 1 부터 N 까지 번 호 를 매 긴 다.N 이 0 일 때 입력 이 끝나 면 이 용례 는 처리 되 지 않 습 니 다.Output 은 모든 테스트 사례 에 대해 1 줄 에서 가장 작은 도로 총 길 이 를 출력 합 니 다.Sample Input 3 1 2 1 1 3 2 2 3 4 4 1 2 1 1 3 4 1 4 1 2 3 3 2 4 2 3 4 5 0 Sample Output 3 5
prime 알고리즘
#include 
#include 
#include 
using namespace std;
const int maxn = 105;
const int INF = 0x3f3f3f3f;
int dis[maxn], n, mp[maxn][maxn];
bool vis[maxn];
void prim() {
    for(int i = 1; i <= n; i++) {
        dis[i] = mp[1][i];
    }
    int ans = 0;
    dis[1] = 0;
    vis[1] = true;
    for(int i = 2; i <= n; i++) {
        int u = INF;
        int pos;
        for(int j = 1; j <= n; j++) {
            if(!vis[j] && u > dis[j]) {
                u = dis[j];
                pos=j;
            }
        }
        if(u == INF) break;
        vis[pos] = true;
        ans += u;
        for(int j = 1; j <= n; j++) {
            if(!vis[j] && dis[j]>mp[pos][j]) {
                dis[j] = mp[pos][j];
            }
        }
    }
    printf("%d
", ans); } int main() { while(scanf("%d", &n) && n) { memset(vis, false, sizeof(vis)); int m = (n-1)*n/2; while(m--) { int u, v, w; scanf("%d %d %d", &u, &v, &w); mp[u][v] = mp[v][u] = w; } prim(); } return 0; }

Kruskal 알고리즘
#include 
#include 
#include 
#include 
using namespace std;
const int MAXN = 10005;
int father[MAXN];
struct node {
    int u, v, value;
}mp[MAXN];
bool cmp(node a, node b) {
    return a.value < b.value;
}
int Find(int x) {
    if(father[x] == x)
        return father[x];
    return father[x] = Find(father[x]);
}
void Union(int a, int b) {
    int fa = Find(a);
    int fb = Find(b);
    if(fa != fb) {
        father[fb] =fa;
    }
}
int Kruskal(int n, int m) {
    sort(mp, mp + m, cmp);
    for(int i = 0; i <= n; i++) {
        father[i] = i;
    }
    int ans = 0;
    for(int i = 0; i < m; i++) {
        int fa = Find(mp[i].u);
        int fb = Find(mp[i].v);
        if(fa != fb) {
            Union(mp[i].u, mp[i].v);
            ans += mp[i].value;
        }
    }
    return ans;
}
int main() {
    int n;
    while(scanf("%d", &n) && n) {
        int m = n*(n-1)/2;
        for(int i = 0; i < m; i++) {
            scanf("%d %d %d", &mp[i].u, &mp[i].v, &mp[i].value);
        }
        printf("%d
", Kruskal(n, m)); } return 0; }

좋은 웹페이지 즐겨찾기