CCF CSP 데이터 센터

© 2015에서 2019 사이 왕 리구 앙은. 모든 권리 보유.이 문서에서는 그렇지 않으면 법적 책임을 추구, 어떤 형태로 허용 된 블로거없이 복제 할 수 없다 블로거 원본입니다. 이 기사를 읽는 것은 당신이 사이트 문 (위 문서를 참조)에 동의 한 것을 의미합니다! 이 문서는, 문제를 스스로 심사의 효율성을 기쁘게 참고 용이며, 블로거는 어떠한 책임도지지 않습니다!
이 링크 : https://blog.csdn.net/happywlg123/article/details/88861244

이름

질문 번호 : 201812-4
질문 이름 : 데이터 센터
시간 제한 : 1.0s
메모리 제한 : 512.0MB
문제 설명 :
여기에 그림 삽입 설명
여기에 그림 삽입 설명

샘플 입력

4
5
1
2 3
1 2 3 4
1 5 4
2 3 8
3 4 2

샘플 출력

4

샘플 설명

다음은 샘플 설명입니다.
여기에 그림 삽입 설명
여기에 그림 삽입 설명

분석

비록 매우 복잡하지만 샘플의주의 깊은 관찰이 발견 된 후, 사실, 최소 스패닝 트리 문제는, 주제 도 어떤 위치에서 루트 노드를 고려해야 할 필요가 없습니다 에 상관없이 한 최소 스패닝 트리가 문제를 추구하지 않기 때문에 어떤 위치하기 때문에, 그것은 주체의 요구 사항을 충족하는 것입니다.

코드

코드 1 : CMP 쓰기 기능, 용기를 사용하지 않고

#include <bits/stdc++.h>
using namespace std;

#define MAX 100001
#define MAXN 500001

struct Edge{
    int u;
    int v;
    int w;
    Edge(){};
    Edge(int u1, int v1, int w1):u(u1), v(v1), w(w1){}
};

int pre[MAXN];
Edge edge[MAX];

bool cmp(Edge e1, Edge e2){
    return e1.w < e2.w;
}

int find(int root){
    int tmp, son;
    son = root;
    while(root != pre[root]){
        root = pre[root];
    }
    while(son != root){
        tmp = pre[son];
        pre[son] = root;
        son = root;
    }
    return root;
}

bool join(int x, int y){
    int rootx = find(x);
    int rooty = find(y);
    if(rootx != rooty){
        pre[rootx] = rooty;
        return true;
    }
    return false;
}

int main(){
    int n = 0, m = 0, root = 0, i = 0, ans = 0, num = 0;
    cin >> n >> m >> root;
    for(i=0; i<n; i++){
        pre[i] = i;
    }
    for(i=0; i<m; i++){
        cin >> edge[i].u >> edge[i].v >> edge[i].w;
    }
    sort(edge, edge+m, cmp);
    for(i=0; i<m; i++){
        if(join(edge[i].u, edge[i].v)){
            ans = edge[i].w;
            num += 1;
            if(num == n-1){
                break;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

코드 2 : 용기를 사용하지 않고, 운영자 <오버로드

#include <bits/stdc++.h>
using namespace std;

#define MAX 100001
#define MAXN 500001

struct Edge{
    int u;
    int v;
    int w;
    Edge(){};
    Edge(int u1, int v1, int w1):u(u1), v(v1), w(w1){}
    bool operator < (struct Edge &e1){
        return this->w < e1.w;
    }
};

int pre[MAXN];
Edge edge[MAX];

int find(int root){
    int tmp, son;
    son = root;
    while(root != pre[root]){
        root = pre[root];
    }
    while(son != root){
        tmp = pre[son];
        pre[son] = root;
        son = root;
    }
    return root;
}

bool join(int x, int y){
    int rootx = find(x);
    int rooty = find(y);
    if(rootx != rooty){
        pre[rootx] = rooty;
        return true;
    }
    return false;
}

int main(){
    int n = 0, m = 0, root = 0, i = 0, ans = 0, num = 0;
    cin >> n >> m >> root;
    for(i=0; i<n; i++){
        pre[i] = i;
    }
    for(i=0; i<m; i++){
        cin >> edge[i].u >> edge[i].v >> edge[i].w;
    }
    sort(edge, edge+m, cmp);
    for(i=0; i<m; i++){
        if(join(edge[i].u, edge[i].v)){
            ans = edge[i].w;
            num += 1;
            if(num == n-1){
                break;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

코드 3 : 오버로드 <연산자, 용기의 사용

#include <bits/stdc++.h>
using namespace std;

struct Edge{
    int u;
    int v;
    int w;
    Edge(){}
    Edge(int u1, int v1, int w1):u(u1), v(v1), w(w1){}
    bool operator < (struct Edge &e1){
        return this->w < e1.w;
    }
};

const int maxn = 500001;
const int maxm = 100001;
int pre[maxn];
vector<Edge> edge;

int findx(int root){
    int son, tmp;
    son = root;
    while(root != pre[root]){
        root  = pre[root];
    }
    while(son != root){
        tmp = pre[son];
        pre[son] = root;
        son = tmp;
    }
    return root;
}

int join(int root1, int root2){
    int x = findx(root1);
    int y = findx(root2);
    if(x != y){
        pre[x] = y;
        return true;
    }
    return false;
}

int main(){
    int n = 0, m = 0, i = 0, ans = 0, num = 0, root = 0;
    int tmp1, tmp2, tmp3;
    cin >> n >> m >> root;
    for(i=0; i<m; i++){
        cin >> tmp1 >> tmp2 >> tmp3;
        edge.push_back(Edge(tmp1, tmp2, tmp3));
    }
    for(i=0; i<n; i++){
        pre[i] = i;
    }
    sort(edge.begin(), edge.end());
    for(vector<Edge>::iterator it = edge.begin(); it != edge.end(); it++){
        if(join(it->u, it->v)){
            ans = it->w;
            num++;
            if(num == n-1){
                cout << ans;
                break;
            }
        }
    }
    return 0;
}

추천

출처blog.csdn.net/happywlg123/article/details/88861244