kuangbin专题六:最小生成树

  不知不觉已经刷到专题六了,但感觉进度还是有点慢了(*  ̄︿ ̄)

 

POJ1251 Jungle Roads

 思路:模板题。

#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int maxn = 505;
int p[maxn];
int n;

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py){
        p[px] = py;
    }
}

int idx;
struct Edge{
    int u, v, w;
} e[maxn];

bool cmp(const Edge& a, const Edge& b){
    return a.w < b.w;
}

void init(){
    for(int i = 0; i <= n; i++) p[i] = i;
    idx = 0;
}

int main(){
    while(cin >> n && n){
        init();

        for(int i = 1; i < n; i++){
            char u, v;
            int k, w;
            cin >> u >> k;
            for(int j = 1; j <= k; j++){
                cin >> v >> w;
                e[idx++] = {u - 'A', v - 'A', w};
            }
        }
        sort(e, e + idx, cmp);

        int res = 0;
        for(int i = 0; i < idx; i++){
            int u = e[i].u, v = e[i].v, w = e[i].w;
            int pu = findP(u), pv = findP(v);
            if(pu != pv){
                res += w;
                Union(u, v);
            }
        }
        cout << res << endl;
    }
    return 0;
}
View Code

 

POJ1287 Networking

思路:模板题。

#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
const int maxn = 1e5;
int p[maxn];
int n, m;

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py){
        p[px] = py;
    }
}

struct Edge{
    int u, v, w;
} e[maxn];

bool cmp(const Edge& a, const Edge& b){
    return a.w < b.w;
}

void init(){
    for(int i = 0; i <= n; i++) p[i] = i;
}

int main(){
    while(cin >> n && n){
        init();

        cin >> m;
        for(int i = 0; i < m; i++){
            cin >> e[i].u >> e[i].v >> e[i].w;
        }
        sort(e, e + m, cmp);

        int res = 0;
        for(int i = 0; i < m; i++){
            int u = e[i].u, v = e[i].v, w = e[i].w;
            int pu = findP(u), pv = findP(v);
            if(pu != pv){
                Union(pu, pv);
                res += w;
            }
        }
        cout << res << endl;
    }
    return 0;
}
View Code

 

POJ2031 Building a Space Station

思路:先连相交的cell,再找最小生成树。

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cmath>
using namespace std;
const int maxn = 1e4 + 5;
int p[maxn];
int n;

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py) p[px] = py;
}

struct Cell{
    double x, y, z, r;
} cell[105];

double dis(Cell &a, Cell &b){
    double dx = a.x - b.x, dy = a.y - b.y, dz = a.z - b.z;
    return sqrt(dx * dx + dy * dy + dz * dz);
}

int idx;
struct Edge{
    int u, v;
    double w;
} e[maxn];

bool cmp(const Edge& a, const Edge& b){
    return a.w < b.w;
}

void init(){
    idx = 0;
    for(int i = 0; i <= n; i++) p[i] = i;
}

int main(){
    while(cin >> n && n){
        init();
        for(int i = 1; i <= n; i++)
            cin >> cell[i].x >> cell[i].y >> cell[i].z >> cell[i].r;

        // check distance between cells
        for(int i = 1; i <= n; i++)
            for(int j = i + 1; j <= n; j++){
                double d = dis(cell[i], cell[j]);
                if(d < cell[i].r + cell[j].r)
                    Union(i, j);
                else{
                    e[idx].u = i;
                    e[idx].v = j;
                    e[idx].w = d - cell[i].r - cell[j].r;
                    idx++;
                }
            }
        sort(e, e + idx, cmp);

        double res = 0;
        for(int i = 0; i < idx; i++){
            int u = e[i].u, v = e[i].v;
            double w = e[i].w;
            int pu = findP(u), pv = findP(v);
            if(pu != pv){
                Union(u, v);
                res += w;
            }
        }
        printf("%.3f\n", res);
    }
    return 0;
}
View Code

 

POJ2421 Constructing Roads

思路:模板题。

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cmath>
using namespace std;
const int maxn = 1e4 + 5;
int p[maxn];
int n, q;

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py) p[px] = py;
}

int idx;
struct Edge{
    int u, v, w;
} e[maxn];

bool cmp(const Edge& a, const Edge& b){
    return a.w < b.w;
}

void init(){
    idx = 0;
    for(int i = 0; i <= n; i++) p[i] = i;
}

int main(){
    cin >> n;
    init();

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++){
            int d;
            cin >> d;
            if(i < j){
                e[idx].u = i, e[idx].v = j;
                e[idx].w = d;
                idx++;
            }
        }
    sort(e, e + idx, cmp);

    cin >> q;
    for(int i = 1; i <= q; i++){
        int u, v;
        cin >> u >> v;
        Union(u, v);
    }

    int res = 0;
    for(int i = 0; i < idx; i++){
        int u = e[i].u, v = e[i].v, w = e[i].w;
        int pu = findP(u), pv = findP(v);
        if(pu != pv){
            Union(u, v);
            res += w;
        }
    }
    cout << res << endl;
    return 0;
}
View Code

 

ZOJ1586 QS Network

思路:模板题。

 

POJ1789 Truck History

思路:模板题。

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 2004;
char code[maxn][8];
int p[maxn];

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

int idx = 0;
struct Edge{
    int u, v, w;
} e[maxn * maxn / 2];

bool cmp(const Edge &x, const Edge &y){
    return x.w < y.w;
}

int dis(int x, int y){
    int d = 0;
    for(int i = 0; i < 7; i++)
        if(code[x][i] != code[y][i])
            d++;
    return d;
}

int main(){
    int N;
    while(cin >> N && N){
        // initialization
        for(int i = 0; i <= N; i++) p[i] = i;
        idx = 0;

        // read code and construct graph
        for(int i = 1; i <= N; i++) cin >> code[i];
        for(int i = 1; i <= N; i++)
            for(int j = i + 1; j <= N; j++){
                e[idx].u = i, e[idx].v = j;
                e[idx].w = dis(i, j);
                idx++;
            }
        sort(e, e + idx, cmp);

        // shortest path
        int res = 0;
        for(int i = 0; i < idx; i++){
            int u = e[i].u, v = e[i].v, w = e[i].w;
            int pu = findP(u), pv = findP(v);
            if(pu != pv){
                res += w;
                Union(u, v);
            }
        }

        cout << "The highest possible quality is 1/" << res << "." << endl;
    }
    return 0;
}
View Code

 

POJ2349 Arctic Network

思路:选出最小生成树,去掉权值最大的几个结点。一直莫名WA让人不爽。抄了以前不知道在哪抄的代码。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 505;
int p[maxn];
int S, P, idx;

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

struct Edge{
    int u, v;
    double w;
}e[maxn * maxn];

bool cmp(const Edge& x, const Edge& y){
    return x.w < y.w;
}

struct Pos{
    int x, y;
} pos[maxn];

double solve(){
    double ans = 0;
    int groupN = P;
    for(int i = 0; i < idx; i++){
        if(groupN <= S) break;
        int u = e[i].u, v = e[i].v;
        double w = e[i].w;
        if(findP(u) == findP(v)) continue;
        Union(u, v);
        ans = w;
        groupN--;
    }
    return ans;
}

int main(){
    int T;
    cin >> T;
    while(T--){
        cin >> S >> P;

        for(int i = 0; i <= P; i++) p[i] = i;

        // read site
        for(int i = 0; i < P; i++)
            cin >> pos[i].x >> pos[i].y;

        idx = 0;
        // connect each site
        for(int i = 0; i < P; i++)
            for(int j = i + 1; j < P; j++){
                int dx = pos[i].x - pos[j].x, dy = pos[i].y - pos[j].y;
                e[idx].u = i, e[idx].v = j;
                e[idx++].w = sqrt(dx * dx + dy * dy);
            }
        sort(e, e + idx, cmp);
        printf("%.2f\n", solve());
    }
    return 0;
}
View Code

 

POJ 1751 Highways

思路:模板题。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 755;
int p[maxn];
int S, P, idx;

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

struct Edge{
    int u, v;
    double w;
}e[maxn * maxn];

bool cmp(const Edge& x, const Edge& y){
    return x.w < y.w;
}

struct Pos{
    int x, y;
} pos[maxn];

int main(){
    int n, m;
    // read data
    cin >> n;
    for(int i = 0; i <= n; i++) p[i] = i;
    for(int i = 1; i <= n; i++)
        cin >> pos[i].x >> pos[i].y;
    cin >> m;
    for(int i = 1; i <= m; i++){
        int u, v;
        cin >> u >> v;
        Union(u, v);
    }

    // construct edge
    int idx = 0;
    for(int i = 1; i <= n; i++)
        for(int j = i + 1; j <= n; j++){
            int dx = pos[i].x - pos[j].x, dy = pos[i].y - pos[j].y;
            e[idx].u = i, e[idx].v = j;
            e[idx++].w = sqrt(dx * dx + dy * dy);
        }
    sort(e, e + idx, cmp);

    for(int i = 0; i < idx; i++){
        int u = e[i].u, v = e[i].v;
        if(findP(u) != findP(v)){
            Union(u, v);
            cout << u << " " << v << endl;
        }
    }
    return 0;
}
View Code

 

POJ1258 Agri-Net

思路:模板题。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int maxn = 105;
int p[maxn];

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

struct Edge{
    int u, v, w;
}e[maxn * maxn];

bool cmp(const Edge& x, const Edge& y){
    return x.w < y.w;
}

int main(){
    int n;
    while(cin >> n){
        for(int i = 0; i <= n; i++) p[i] = i;

        int idx = 0;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++){
                int x;
                cin >> x;
                if(i < j){
                    e[idx].u = i, e[idx].v = j;
                    e[idx++].w = x;
                }
            }
        sort(e, e + idx, cmp);

        int ans = 0;
        for(int i = 0; i < idx; i++){
            int u = e[i].u, v = e[i].v;
            if(findP(u) != findP(v)){
                Union(u, v);
                ans += e[i].w;
            }
        }
        cout << ans << endl;
    }
    return 0;
}
View Code

 

POJ3026 Borg Maze

 思路:先建图,再模板。这题以前我弟出给我做过,当时居然不会,丢人了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 55 * 55;
const int maxm = 55;
int p[maxn];
char maze[maxm][maxm];
int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
int x, y;

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

struct Edge{
    int u, v, w;
}e[maxn * maxn];

bool cmp(const Edge& x, const Edge& y){
    return x.w < y.w;
}

struct Pos{
    int x, y;
};

int dis[maxm][maxm];
void bfs(int r, int c){
    memset(dis, 0x3f, sizeof(dis));
    dis[r][c] = 0;
    queue<Pos> q;
    Pos pos = {r, c};
    q.push(pos);
    while(q.size()){
        Pos p = q.front(); q.pop();
        int px = p.x, py = p.y;
        for(int i = 0; i < 4; i++){
            int nx = px + dx[i], ny = py + dy[i];
            if(nx < 1 || nx > y || ny < 1 || ny > x) continue;
            if(maze[nx][ny] != '#' && dis[nx][ny] == 0x3f3f3f3f){
                Pos np = {nx, ny};
                q.push(np);
                dis[nx][ny] = dis[px][py] + 1;
            }
        }
    }
}

int main(){
    int T;
    cin >> T;
    while(T--){
        cin >> x >> y;

        for(int i = 0; i <= x * y; i++) p[i] = i;

        vector<Pos> v;
        // read maze
        char line[maxm];
        fgets(line, maxm, stdin);
        for(int i = 1; i <= y; i++){
            fgets(line, maxm, stdin);
            for(int j = 1; j <= x; j++){
                maze[i][j] = line[j-1];
                if(maze[i][j] == 'S' || maze[i][j] == 'A'){
                    Pos p = {i, j};
                    v.push_back(p);
                }
            }
        }

        int idx = 0;
        // build connection by bfs
        for(int i = 0; i < v.size(); i++){
            bfs(v[i].x, v[i].y);
            for(int j = 0; j < v.size(); j++){
                if(i == j) continue;
                e[idx].u = i, e[idx].v = j;
                e[idx++].w = dis[v[j].x][v[j].y];
            }
        }
        sort(e, e + idx, cmp);

        int ans = 0;
        // get output
        for(int i = 0; i < idx; i++){
            int u = e[i].u, v = e[i].v, w = e[i].w;
            if(findP(u) != findP(v)){
                Union(u, v);
                ans += w;
            }
        }
        cout << ans << endl;
    }
    return 0;
}
View Code

 

POJ1679 The Unique MST

思路:次小生成树。

 

HDU1233 还是畅通工程

思路:模板题。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 105;
int p[maxn];

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

struct Edge{
    int u, v, w;
}e[maxn * maxn];

bool cmp(const Edge& x, const Edge& y){
    return x.w < y.w;
}

int main(){
    int N;
    while(scanf("%d", &N) && N){
        for(int i = 0; i <= N; i++) p[i] = i;

        int idx = 0;
        for(int i = 1; i <= N * (N - 1) / 2; i++){
            scanf("%d%d%d", &e[idx].u, &e[idx].v, &e[idx].w);
            idx++;
        }
        sort(e, e + idx, cmp);

        int ans = 0;
        for(int i = 0; i < idx; i++){
            int u = e[i].u, v = e[i].v, w = e[i].w;
            if(findP(u) != findP(v)){
                Union(u, v);
                ans += w;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

 

HDU1301 Jungle Roads

思路:模板题。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 105;
int p[maxn];

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

struct Edge{
    int u, v, w;
}e[maxn * maxn];

bool cmp(const Edge& x, const Edge& y){
    return x.w < y.w;
}

int main(){
    int N;
    while(cin >> N && N){
        for(int i = 0; i <= N; i++) p[i] = i;

        int idx = 0;
        for(int i = 1; i < N; i++){
            char u;
            int k;
            cin >> u >> k;
            while(k--){
                char v;
                int w;
                cin >> v >> w;
                e[idx].u = u - 'A';
                e[idx].v = v - 'A';
                e[idx].w = w;
                idx++;
            }
        }
        sort(e, e + idx, cmp);

        int ans = 0;
        for(int i = 0; i < idx; i++){
            int u = e[i].u, v = e[i].v, w = e[i].w;
            if(findP(u) != findP(v)){
                Union(u, v);
                ans += w;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
View Code

 

HDU1875 畅通工程再续

思路:模板题。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn = 105;
int p[maxn];

int findP(int x){
    return x == p[x] ? p[x] : p[x] = findP(p[x]);
}

void Union(int x, int y){
    int px = findP(x), py = findP(y);
    if(px != py)
        p[px] = py;
}

struct Edge{
    int u, v;
    double w;
}e[maxn * maxn];

bool cmp(const Edge& x, const Edge& y){
    return x.w < y.w;
}

struct Pos{
    int x, y;
} pos[maxn];

double dis(Pos &a, Pos &b){
    int dx = a.x - b.x, dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

int main(){
    int T;
    cin >> T;
    while (T--){
        int C;
        cin >> C;

        for(int i = 0; i <= C; i++) p[i] = i;

        for(int i = 1; i <= C; i++)
            cin >> pos[i].x >> pos[i].y;

        int idx = 0;
        for(int i = 1; i <= C; i++)
            for(int j = i + 1; j <= C; j++){
                double d = dis(pos[i], pos[j]);
                if(d >= 10 && d <= 1000){
                    e[idx].u = i, e[idx].v = j;
                    e[idx++].w = d;
                }
            }
        sort(e, e + idx, cmp);

        double ans = 0;
        for(int i = 0; i < idx; i++){
            if(findP(e[i].u) != findP(e[i].v)){
                Union(e[i].u, e[i].v);
                ans += e[i].w;
            }
        }

        bool reachAll = true;
        for(int i = 1; i <= C; i++)
            if(findP(1) != findP(i))
                reachAll = false;
        if(reachAll)
            printf("%.1f\n", ans * 100);
        else
            printf("oh!\n");
    }
    return 0;
}
View Code

 

posted @ 2021-02-05 11:18  Nanachi  阅读(48)  评论(0)    收藏  举报