数据结构与算法实验6——图论

7-7 家庭房产

#include <bits/stdc++.h>
const int N = 1e5 + 10;
using namespace std;
int p[N], si[N], sum[N], area[N], n;
bool st[N];
struct node {
    int id, si;
    double sum, area;
};
bool cmp(node a, node b) {
    if (a.area == b.area) return a.id < b.id;
    return a.area > b.area;
}
int find(int x) {
    if (x == p[x]) return x;
    return p[x] = find(p[x]);
}
void merge(int a, int b) {
    a = find(a), b = find(b);
    if (a != b) {
        if (a < b) swap(a, b);
        p[a] = b;
        si[b] += si[a];
        sum[b] += sum[a];
        area[b] += area[a];
    }
}
int main() {
    cin >> n;
    for (int i = 0; i <= 1e5; i++) {
        p[i] = i;
        si[i] = 1;
    }
    for (int i = 1; i <= n; i++) {
        int x, f, m, k;
        cin >> x >> f >> m;
        st[x] = 1;
        if (f != -1) st[f] = 1, merge(x, f);
        if (m != -1) st[m] = 1, merge(x, m);
        cin >> k;
        while (k--) {
            int id;
            cin >> id;
            st[id] = 1;
            merge(x, id);
        }
        cin >> f >> m;
        sum[find(x)] += f;
        area[find(x)] += m;
    }
    vector<node> res;
    for (int i = 0; i <= 1e5; i++) {
        if (st[i] && find(i) == i) {
            res.push_back({i, si[i], sum[i] / (si[i] * 1.0), area[i] / (si[i] * 1.0)});
        }
    }
    sort(res.begin(), res.end(), cmp);
    cout << res.size() << endl;
    for (int i = 0 ; i < res.size() ; i++) {
        node it = res[i];
        printf("%04d %.d %.3f %.3f\n", it.id, it.si, it.sum, it.area);
    }
}

7-8 森森美图

#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#define INF 1e9

const int N = 110;
using namespace std;
typedef pair<int, int> PII;
int X1, Y1, X2, Y2;
int n, m, flag = 1;
int g[N][N];
double dist[N][N];

int dx[] = {-1, 1, -1, 1, 1, -1, 0, 0}, dy[] = {-1, 1, 1, -1, 0, 0, 1, -1};

bool check1(int x, int y) {
    double t = (X2 - X1) * (y - Y1) - (Y2 - Y1) * (x - X1);
    if (flag * t > 0 || x == X2 && y == Y2) return true;
    return false;
}
bool check2(int x, int y) { return x >= 0 && x < n && y >= 0 && y < m; }

double bfs() {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            dist[i][j] = INF;
        }
    }
    queue<PII> q;
    dist[X1][Y1] = g[X1][Y1];
    q.push({X1, Y1});

    while (q.size()) {
        auto t = q.front();
        q.pop();
        for (int i = 0; i < 8; i++) {
            int x = t.first + dx[i], y = t.second + dy[i];
            if (check2(x, y) && check1(x, y)) {
                double w = g[x][y];
                if (i < 4) w += (sqrt(2) - 1) * (g[t.first][t.second] + g[x][y]);
                if (dist[x][y] > dist[t.first][t.second] + w) {
                    dist[x][y] = dist[t.first][t.second] + w;
                    q.push({x, y});
                }
            }
        }
    }
    flag = -1;
    return dist[X2][Y2];
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> g[i][j];
        }
    }
    cin >> Y1 >> X1 >> Y2 >> X2;
    printf("%.2f", bfs() + bfs() - g[X1][Y1] - g[X2][Y2]);
}

7-9 哥尼斯堡的“七桥问题”

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>

const int N = 1e3 + 10;
using namespace std;
int du[N], p[N];
int find(int x) {
    if (x == p[x]) return x;
    return p[x] = find(p[x]);
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> v(n + 1);
    for (int i = 1; i <= n; i++) {
        p[i] = i;
    }
    while (m--) {
        int a, b;
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
        a = find(a), b = find(b);
        if (a != b) p[a] = b;
    }
    int res = 1;
    for (int i = 1; i <= n; i++) {
        if (find(i) != find(1) || v[i].size() && v[i].size() & 1) {
            res = 0;
            break;
        }
    }
    cout << res;
}

7-10 公路村村通

#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int N = 100010, M = 200010, INF = 0x3f3f3f3f;
int n, m;
int p[N];

struct Edge {
    int a, b, w;
    bool operator<(const Edge &W) const { return w < W.w; }
} edges[M];

int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void kruskal() {
    sort(edges, edges + m);
    for (int i = 1; i <= n; i++) p[i] = i;
    int res = 0, cnt = 0;
    for (int i = 0; i < m; i++) {
        int a = edges[i].a, b = edges[i].b, w = edges[i].w;
        a = find(a), b = find(b);
        if (a != b) {
            p[a] = b;
            res += w;
            cnt++;
        }
    }
    if (cnt < n - 1) puts("-1");
    else cout << res;
}

int main() {
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        edges[i] = {a, b, w};
    }
    kruskal();
    return 0;
}

7-11 旅游规划

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#define INF 0x3f3f3f3f

const int N = 1e4 + 10, M = 1e7 + 10;

using namespace std;

int h[N], e[M], w1[M], w2[M], ne[M], idx;
int dist[N], cost[N];
bool st[N];
int n, m, S, T;
void add(int a, int b, int c, int d) {
    e[idx] = b;
    w1[idx] = c;
    w2[idx] = d;
    ne[idx] = h[a];
    h[a] = idx++;
}

void spfa() {
    memset(dist, 0x3f, sizeof dist);
    dist[S] = cost[S] = 0;
    queue<int> q;
    q.push(S);
    st[S] = true;
    while (q.size()) {
        int t = q.front();
        q.pop();
        st[t] = false;
        for (int i = h[t]; i != -1; i = ne[i]) {
            int j = e[i];
            if (dist[j] > dist[t] + w1[i]) {
                dist[j] = dist[t] + w1[i];
                cost[j] = cost[t] + w2[i];
                if (!st[j]) {
                    q.push(j);
                    st[j] = true;
                }
            }
            if (dist[j] == dist[t] + w1[i]) {
                cost[j] = min(cost[j], cost[t] + w2[i]);
            }
        }
    }
    cout << dist[T] << ' ' << cost[T];
}

int main() {
    cin >> n >> m >> S >> T;
    memset(h, -1, sizeof h);
    for (int i = 1; i <= m; i++) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        add(a, b, c, d);
        add(b, a, c, d);
    }
    spfa();
}

7-12 关键活动

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
const int N = 1e5 + 10;

using namespace std;
int du[N];
int t1[N], t2[N];
queue<int> q;
vector<int> res;
struct node {
    int e, w;
};

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<node>> v(n + 1);
    while (m--) {
        int a, b, c;
        cin >> a >> b >> c;
        v[a].push_back({b, c});
        du[b]++;
    }
    for (int i = 1; i <= n; i++) {
        if (du[i] == 0) {
            q.push(i);
            res.push_back(i);
        }
    }
    while (q.size()) {
        int t = q.front();
        q.pop();
        for (auto it : v[t]) {
            int e = it.e, w = it.w;
            du[e]--;
            if (du[e] == 0) {
                q.push(e);
                res.push_back(e);
            }
            t1[e] = max(t1[e], t1[t] + w);
        }
    }
    if (res.size() != n)
        puts("0");
    else {
        int ans = 0;
        for (int i = 1; i <= n; i++) {
            ans = max(ans, t1[i]);
        }
        fill(t2 + 1, t2 + 1 + n, ans);
        for (int i = res.size() - 1; i >= 0; i--) {
            int j = res[i];
            for (auto it : v[j]) {
                int e = it.e, w = it.w;
                t2[j] = min(t2[j], t2[e] - w);
            }
        }
        cout << ans << endl;
        for (int i = 1; i <= n; i++) {
            for (int j = v[i].size() - 1; j >= 0; j--) {
                int e = v[i][j].e, w = v[i][j].w;
                if (t1[i] + w == t2[e]) {
                    cout << i << "->" << e << endl;
                }
            }
        }
    }
}

7-13 任务调度的合理性

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
const int N = 1e5 + 10;

using namespace std;
int du[N];
int dist[N];
unordered_map<int, int> pre;

int main() {
    int n;
    cin >> n;
    vector<vector<int>> v(n + 1);
    for (int i = 1; i <= n; i++) {
        int k, x;
        cin >> k;
        du[i] = k;
        while (k--) {
            cin >> x;
            v[x].push_back(i);
        }
    }
    queue<int> q;
    vector<int> res;
    for (int i = 1; i <= n; i++) {
        if (du[i] == 0) {
            q.push(i);
            res.push_back(i);
        }
    }

    while (q.size()) {
        int t = q.front();
        q.pop();
        for (auto it : v[t]) {
            du[it]--;
            if (du[it] == 0) {
                q.push(it);
                res.push_back(it);
            }
        }
    }
    if (res.size() != n)
        puts("0");
    else
        puts("1");
}

7-14 最短工期

#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>

const int N = 1e5 + 10;

using namespace std;
int du[N];
int dist[N];
struct node {
    int e, w;
};
int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<node>> v(n);
    while (m--) {
        int a, b, c;
        cin >> a >> b >> c;
        v[a].push_back({b, c});
        du[b]++;
    }
    queue<int> q;
    int res = 0;
    for (int i = 0; i < n; i++) {
        if (du[i] == 0) {
            q.push(i);
            for (auto j : v[i]) {
                dist[j.e] = max(dist[j.e], dist[i] + j.w);
            }
            res++;
        }
    }

    while (q.size()) {
        int t = q.front();
        q.pop();
        for (auto it : v[t]) {
            du[it.e]--;
            if (du[it.e] == 0) {
                q.push(it.e);
                for (auto j : v[it.e]) {
                    dist[j.e] = max(dist[j.e], dist[it.e] + j.w);
                }
                res++;
            }
        }
    }
    if (res != n)
        puts("Impossible");
    else {
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans = max(ans, dist[i]);
        }
        cout << ans;
    }
}

7-15 最短路径

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
using namespace std;
const int N = 100100, M = N;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
bool st[N];
int S, T;
void add(int a, int b, int c) {
    e[idx] = b;
    w[idx] = c;
    ne[idx] = h[a];
    h[a] = idx++;
}

void spfa() {
    memset(dist, 0x3f, sizeof dist);
    dist[S] = 0;
    queue<int> q;
    q.push(S);
    st[S] = true;
    while (q.size()) {
        int t = q.front();
        q.pop();
        st[t] = false;
        for (int i = h[t]; i != -1; i = ne[i]) {
            int j = e[i];
            if (dist[j] > dist[t] + w[i]) {
                dist[j] = dist[t] + w[i];
                if (!st[j]) {
                    q.push(j);
                    st[j] = true;
                }
            }
        }
    }
    if (dist[T] > 1e8)
        printf("There is no path between %d and %d.", S, T);
    else
        printf("The length of the shortest path between %d and %d is %d.\n", S,
               T, dist[T]);
}

int main() {
    memset(h, -1, sizeof h);
    int n, m;
    cin >> n >> m;
    while (m--) {
        int a, b;
        cin >> a >> b;
        add(a, b, 1);
        add(b, a, 1);
    }
    cin >> S >> T;
    spfa();
}

7-16 最短路径算法(Floyd-Warshall)

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
const int N = 1100;
int g[N][N];
int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> g[i][j];
            if (i != j && g[i][j] == 0) g[i][j] = 1e9;
        }
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (g[i][j] > 1e9 / 2 && i != j) g[i][j] = -1;
            cout << g[i][j] << ' ';
        }
        puts("");
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值