【算法笔记自学】第 10 章 提高篇(4)——图算法专题

news2024/9/23 21:32:20

10.1图的定义和相关术语

#include <cstdio>

const int MAXN = 100;
int degree[MAXN] = {0};

int main() {
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int j = 0; j < m; j++) {
        scanf("%d%d", &u, &v);
        degree[u]++;
        degree[v]++;
    }
    for (int i = 0; i < n; i++) {
        printf("%d", degree[i]);
        if (i < n - 1) {
            printf(" ");
        }
    }
    return 0;
}

#include <cstdio>

const int MAXN = 100;
int inDegree[MAXN] = {0};
int outDegree[MAXN] = {0};

int main() {
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int j = 0; j < m; j++) {
        scanf("%d%d", &u, &v);
        outDegree[u]++;
        inDegree[v]++;
    }
    for (int i = 0; i < n; i++) {
        printf("%d %d\n", inDegree[i], outDegree[i]);
    }
    return 0;
}

10.2图的存储

#include <cstdio>
#include <cstring>

const int MAXN = 100;
int G[MAXN][MAXN];

int main() {
    memset(G, 0, sizeof(G));
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u][v] = G[v][u] = 1;
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d", G[i][j]);
            printf(j < n - 1 ? " " : "\n");
        }
    }
    return 0;
}

#include <cstdio>
#include <cstring>

const int MAXN = 100;
int G[MAXN][MAXN];

int main() {
    memset(G, 0, sizeof(G));
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u][v] = 1;
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d", G[i][j]);
            printf(j < n - 1 ? " " : "\n");
        }
    }
    return 0;
}

#include <cstdio>
#include <vector>
using namespace std;

const int MAXN = 100;
vector<int> G[MAXN];

int main() {
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for (int i = 0; i < n; i++) {
        printf("%d(%d)", i, (int)G[i].size());
        for (int j = 0; j < G[i].size(); j++) {
            printf(" %d", G[i][j]);
        }
        printf("\n");
    }
    return 0;
}

#include <cstdio>
#include <vector>
using namespace std;

const int MAXN = 100;
vector<int> G[MAXN];

int main() {
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
    }
    for (int i = 0; i < n; i++) {
        printf("%d(%d)", i, (int)G[i].size());
        for (int j = 0; j < G[i].size(); j++) {
            printf(" %d", G[i][j]);
        }
        printf("\n");
    }
    return 0;
}

10.3图的遍历

#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

const int MAXN = 100;
vector<int> G[MAXN];
bool vis[MAXN];

void DFS(int u) {
    vis[u] = true;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (!vis[v]) {
            DFS(v);
        }
    }
}

int main() {
    memset(vis, false, sizeof(vis));
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    int blockCount = 0;
    for (int i = 0; i < n; i++) {
        if (!vis[i]) {
            DFS(i);
            blockCount++;
        }
    }
    printf("%d", blockCount);
    return 0;
}

#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

const int MAXN = 100;
vector<int> G[MAXN];
bool vis[MAXN];

void DFS(int u) {
    vis[u] = true;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (!vis[v]) {
            DFS(v);
        }
    }
}

int main() {
    memset(vis, false, sizeof(vis));
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    int blockCount = 0;
    for (int i = 0; i < n; i++) {
        if (!vis[i]) {
            DFS(i);
            blockCount++;
        }
    }
    printf(blockCount == 1 ? "Yes" : "No");
    return 0;
}

#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;

const int MAXN = 100;
vector<int> G[MAXN];
int vis[MAXN];

bool isCyclic(int u) {
    vis[u] = 0;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (vis[v] == -1 && isCyclic(v)) {
            return true;
        } else if (vis[v] == 0) {
            return true;
        }
    }
    vis[u] = 1;
    return false;
}

int main() {
    memset(vis, -1, sizeof(vis));
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
    }
    int isCyclicResult = false;
    for (int i = 0; i < n; i++) {
        if (vis[i] == -1 && isCyclic(i)) {
            isCyclicResult = true;
        }
        if (isCyclicResult) {
            break;
        }
    }
    printf(isCyclicResult ? "Yes" : "No");
    return 0;
}

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

const int MAXN = 100;
int weight[MAXN];
vector<int> G[MAXN];
bool vis[MAXN];

int DFS(int u) {
    vis[u] = true;
    int weightSum = weight[u];
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (!vis[v]) {
            weightSum += DFS(v);
        }
    }
    return weightSum;
}

int main() {
    memset(vis, false, sizeof(vis));
    int n, m, u, v;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d", &weight[i]);
    }
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    int maxWeightSum = 0;
    for (int i = 0; i < n; i++) {
        if (!vis[i]) {
            maxWeightSum = max(maxWeightSum, DFS(i));
        }
    }
    printf("%d", maxWeightSum);
    return 0;
}

#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

const int MAXN = 100;
vector<int> G[MAXN];
bool inQueue[MAXN] = {false};
int layers[MAXN];

void BFS(int s) {
    queue<int> q;
    q.push(s);
    inQueue[s] = true;
    int layer = 0;
    while (!q.empty()) {
        int cnt = q.size();
        for (int i = 0; i < cnt; i++) {
            int front = q.front();
            q.pop();
            layers[front] = layer;
            for (int j = 0; j < G[front].size(); j++) {
                int v = G[front][j];
                if (!inQueue[v]) {
                    q.push(v);
                    inQueue[v] = true;
                }
            }
        }
        layer++;
    }
}

int main() {
    int n, m, start, u, v;
    scanf("%d%d%d", &n, &m, &start);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    BFS(start);
    for (int i = 0; i < n; i++) {
        printf("%d", layers[i]);
        if (i < n - 1) {
            printf(" ");
        }
    }
    return 0;
}

#include <cstdio>
#include <vector>
#include <queue>
using namespace std;

const int MAXN = 100;
vector<int> G[MAXN];
bool inQueue[MAXN] = {false};

int BFS(int s, int maxLayer) {
    queue<int> q;
    q.push(s);
    inQueue[s] = true;
    int layer = 0;
    int vertexCount = 0;
    while (!q.empty() && layer <= maxLayer) {
        int cnt = q.size();
        vertexCount += cnt;
        for (int i = 0; i < cnt; i++) {
            int front = q.front();
            q.pop();
            for (int j = 0; j < G[front].size(); j++) {
                int v = G[front][j];
                if (!inQueue[v]) {
                    q.push(v);
                    inQueue[v] = true;
                }
            }
        }
        layer++;
    }
    return vertexCount;
}

int main() {
    int n, m, start, maxLayer, u, v;
    scanf("%d%d%d%d", &n, &m, &start, &maxLayer);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
    }
    int vertexCount = BFS(start, maxLayer);
    printf("%d", vertexCount);
    return 0;
}

10.4最短路径

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

const int MAXN = 100;
const int INF = 1e9;

struct Edge {
    int v, dis;
    Edge(int _v, int _dis) {
        v = _v, dis = _dis;
    }
};

vector<Edge> G[MAXN];
int d[MAXN];
bool vis[MAXN];

void dijkstra(int n, int s) {
    fill(d, d + MAXN, INF);
    memset(vis, false, sizeof(vis));
    d[s] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, minDis = INF;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && d[j] < minDis) {
                u = j;
                minDis = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        vis[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int dis = G[u][j].dis;
            if (!vis[v] && d[u] + dis < d[v]) {
                d[v] = d[u] + dis;
            }
        }
    }
}

int main() {
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        G[v].push_back(Edge(u, w));
    }
    dijkstra(n, s);
    if (d[t] == INF) {
        printf("-1");
    } else {
        printf("%d", d[t]);
    }
    return 0;
}

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

const int MAXN = 100;
const int INF = 1e9;

struct Edge {
    int v, dis;
    Edge(int _v, int _dis) {
        v = _v, dis = _dis;
    }
};

vector<Edge> G[MAXN];
int d[MAXN];
bool vis[MAXN];

void dijkstra(int n, int s) {
    fill(d, d + MAXN, INF);
    memset(vis, false, sizeof(vis));
    d[s] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, minDis = INF;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && d[j] < minDis) {
                u = j;
                minDis = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        vis[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int dis = G[u][j].dis;
            if (!vis[v] && d[u] + dis < d[v]) {
                d[v] = d[u] + dis;
            }
        }
    }
}

int main() {
    int n, m, s;
    scanf("%d%d%d", &n, &m, &s);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        G[v].push_back(Edge(u, w));
    }
    dijkstra(n, s);
    for (int i = 0; i < n; i++) {
        if (d[i] == INF) {
            printf("-1");
        } else {
            printf("%d", d[i]);
        }
        if (i < n - 1) {
            printf(" ");
        }
    }
    return 0;
}

 

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

const int MAXN = 100;
const int INF = 1e9;

struct Edge {
    int v, dis, cost;
    Edge(int _v, int _dis, int _cost) {
        v = _v, dis = _dis, cost = _cost;
    }
};

vector<Edge> G[MAXN];
int d[MAXN], c[MAXN];
bool vis[MAXN];

void dijkstra(int n, int s) {
    fill(d, d + MAXN, INF);
    fill(c, c + MAXN, INF);
    memset(vis, false, sizeof(vis));
    d[s] = 0;
    c[s] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, minDis = INF;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && d[j] < minDis) {
                u = j;
                minDis = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        vis[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int dis = G[u][j].dis;
            int cost = G[u][j].cost;
            if (!vis[v]) {
                if (d[u] + dis < d[v]) {
                    d[v] = d[u] + dis;
                    c[v] = c[u] + cost;
                } else if (d[u] + dis == d[v] && c[u] + cost < c[v]) {
                    c[v] = c[u] + cost;
                }
            }
        }
    }
}

int main() {
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, dis, cost;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d%d", &u, &v, &dis, &cost);
        G[u].push_back(Edge(v, dis, cost));
        G[v].push_back(Edge(u, dis, cost));
    }
    dijkstra(n, s);
    printf("%d %d", d[t], c[t]);
    return 0;
}

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

const int MAXN = 100;
const int INF = 1e9;

struct Edge {
    int v, dis;
    Edge(int _v, int _dis) {
        v = _v, dis = _dis;
    }
};

vector<Edge> G[MAXN];
int d[MAXN], pathCount[MAXN];
bool vis[MAXN];

void dijkstra(int n, int s) {
    fill(d, d + MAXN, INF);
    memset(pathCount, 0, sizeof(pathCount));
    memset(vis, false, sizeof(vis));
    d[s] = 0;
    pathCount[s] = 1;
    for (int i = 0; i < n; i++) {
        int u = -1, minDis = INF;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && d[j] < minDis) {
                u = j;
                minDis = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        vis[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int dis = G[u][j].dis;
            if (!vis[v]) {
                if (d[u] + dis < d[v]) {
                    d[v] = d[u] + dis;
                    pathCount[v] = pathCount[u];
                } else if (d[u] + dis == d[v]) {
                    pathCount[v] += pathCount[u];
                }
            }
        }
    }
}

int main() {
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        G[v].push_back(Edge(u, w));
    }
    dijkstra(n, s);
    printf("%d %d", d[t], pathCount[t]);
    return 0;
}

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

const int MAXN = 100;
const int INF = 1e9;

struct Edge {
    int v, dis;
    Edge(int _v, int _dis) {
        v = _v, dis = _dis;
    }
};

vector<Edge> G[MAXN];
int d[MAXN], pre[MAXN];
bool vis[MAXN];

void dijkstra(int n, int s) {
    fill(d, d + MAXN, INF);
    memset(pre, -1, sizeof(pre));
    memset(vis, false, sizeof(vis));
    d[s] = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, minDis = INF;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && d[j] < minDis) {
                u = j;
                minDis = d[j];
            }
        }
        if (u == -1) {
            return;
        }
        vis[u] = true;
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int dis = G[u][j].dis;
            if (!vis[v] && d[u] + dis < d[v]) {
                d[v] = d[u] + dis;
                pre[v] = u;
            }
        }
    }
}

vector<int> path;

void DFS(int v, int s) {
    if (v == s) {
        path.push_back(v);
        return;
    }
    DFS(pre[v], s);
    path.push_back(v);
}

int main() {
    int n, m, s, t;
    scanf("%d%d%d%d", &n, &m, &s, &t);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        G[v].push_back(Edge(u, w));
    }
    dijkstra(n, s);
    DFS(t, s);
    printf("%d ", d[t]);
    for (int i = 0; i < path.size(); i++) {
        printf("%d", path[i]);
        if (i < (int)path.size() - 1) {
            printf("->");
        }
    }
    return 0;
}

#include <cstdio>
#include <algorithm>
using namespace std;

const int MAXN = 50;
const int INF = 1e9;

int d[MAXN][MAXN];

void floyd(int n) {
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (d[i][k] != INF && d[k][j] != INF && d[i][k] + d[k][j] < d[i][j]) {
                    d[i][j] = d[i][k] + d[k][j];
                }
            }
        }
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    fill(d[0], d[0] + MAXN * MAXN, INF);
    for (int i = 0; i < n; i++) {
        d[i][i] = 0;
    }
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        d[u][v] = d[v][u] = w;
    }
    floyd(n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (d[i][j] == INF) {
                printf("-1");
            } else {
                printf("%d", d[i][j]);
            }
            if (j < n - 1) {
                printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}

10.5最小生成树

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

const int MAXN = 500;
const int INF = 1e9;

struct Edge {
    int v, dis;
    Edge(int _v, int _dis) {
        v = _v, dis = _dis;
    }
};

vector<Edge> G[MAXN];
int d[MAXN];
bool vis[MAXN];

int prim(int n) {
    fill(d, d + MAXN, INF);
    memset(vis, false, sizeof(vis));
    d[0] = 0;
    int weightSum = 0;
    for (int i = 0; i < n; i++) {
        int u = -1, minDis = INF;
        for (int j = 0; j < n; j++) {
            if (!vis[j] && d[j] < minDis) {
                u = j;
                minDis = d[j];
            }
        }
        if (u == -1) {
            return -1;
        }
        vis[u] = true;
        weightSum += d[u];
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int dis = G[u][j].dis;
            if (!vis[v] && dis < d[v]) {
                d[v] = dis;
            }
        }
    }
    return weightSum;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        G[v].push_back(Edge(u, w));
    }
    int weightSum = prim(n);
    printf("%d", weightSum);
    return 0;
}

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

const int MAXN = 10000;

struct Edge {
    int u, v, w;
    Edge(int _u, int _v, int _w) {
        u = _u, v = _v, w = _w;
    }
};

vector<Edge> edges;

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

int father[MAXN];

int findFather(int x) {
    int xCopy = x;
    while (father[x] != x) {
        x = father[x];
    }
    int root = x;
    x = xCopy;
    while (father[x] != x) {
        int fatherX = father[x];
        father[x] = root;
        x = fatherX;
    }
    return root;
}

int kruskal(int n, int m) {
    for (int i = 0; i < n; i++) {
        father[i] = i;
    }
    int weightSum = 0, edgeCount = 0;
    sort(edges.begin(), edges.end(), cmp);
    for (int i = 0; i < m; i++) {
        int faU = findFather(edges[i].u);
        int faV = findFather(edges[i].v);
        if (faU != faV) {
            father[faU] = faV;
            weightSum += edges[i].w;
            edgeCount++;
        }
        if (edgeCount == n - 1) {
            break;
        }
    }
    if (edgeCount != n - 1) {
        return -1;
    } else {
        return weightSum;
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        edges.push_back(Edge(u, v, w));
    }
    int weightSum = kruskal(n, m);
    printf("%d", weightSum);
    return 0;
}

10.6拓扑排序

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int MAXN = 100;

vector<int> G[MAXN];
int inDegree[MAXN];
vector<int> topoOrder;

void topoSort(int n) {
    priority_queue<int, vector<int>, greater<int> > q;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.top();
        q.pop();
        topoOrder.push_back(u);
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            inDegree[v]--;
            if (inDegree[v] == 0) {
                q.push(v);
            }
        }
        G[u].clear();
    }
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        inDegree[v]++;
    }
    topoSort(n);
    for (int i = 0; i < topoOrder.size(); i++) {
        printf("%d", topoOrder[i]);
        if (i < (int)topoOrder.size() - 1) {
            printf(" ");
        }
    }
    return 0;
}

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int MAXN = 100;

vector<int> G[MAXN];
int inDegree[MAXN];

bool topoSort(int n) {
    int vertexCount = 0;
    priority_queue<int, vector<int>, greater<int> > q;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.top();
        q.pop();
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            inDegree[v]--;
            if (inDegree[v] == 0) {
                q.push(v);
            }
        }
        G[u].clear();
        vertexCount++;
    }
    return vertexCount == n;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        inDegree[v]++;
    }
    printf(topoSort(n) ? "Yes" : "No");
    return 0;
}

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int MAXN = 100;

vector<int> G[MAXN];
int inDegree[MAXN];
vector<int> topoOrder;

int topoSort(int n) {
    int vertexCount = 0;
    priority_queue<int, vector<int>, greater<int> > q;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.top();
        q.pop();
        topoOrder.push_back(u);
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i];
            inDegree[v]--;
            if (inDegree[v] == 0) {
                q.push(v);
            }
        }
        G[u].clear();
        vertexCount++;
    }
    return vertexCount;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v;
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        inDegree[v]++;
    }
    int learnCount = topoSort(n);
    if (learnCount == n) {
        printf("Yes\n");
        for (int i = 0; i < topoOrder.size(); i++) {
            printf("%d", topoOrder[i]);
            if (i < (int)topoOrder.size() - 1) {
                printf(" ");
            }
        }
    } else {
        printf("No\n%d\n", n - learnCount);
    }
    return 0;
}

10.7关键路径

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;

const int MAXN = 100;

struct Edge {
    int v, w;
    Edge(int _v, int _w) {
        v = _v, w = _w;
    }
};

vector<Edge> G[MAXN];
int inDegree[MAXN] = {0};
vector<int> topoOrder;
int ve[MAXN], vl[MAXN];
vector<int> activity[MAXN];

bool topoSort(int n) {
    priority_queue<int, vector<int>, greater<int> > q;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.top();
        q.pop();
        topoOrder.push_back(u);
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            inDegree[v]--;
            if (inDegree[v] == 0) {
                q.push(v);
            }
            if (ve[u] + G[u][i].w > ve[v]) {
                ve[v] = ve[u] + G[u][i].w;
            }
        }
    }
    return (int)topoOrder.size() == n;
}

int getCriticalPathLength(int n) {
    memset(ve, 0, sizeof(ve));
    if (!topoSort(n)) {
        return -1;
    }
    int maxLength = 0;
    for(int i = 0; i < n; i++) {
        if(ve[i] > maxLength) {
            maxLength = ve[i];
        }
    }
    return maxLength;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        inDegree[v]++;
    }
    int pathLength = getCriticalPathLength(n);
    if (pathLength == -1) {
        printf("No");
    } else {
        printf("Yes\n%d", pathLength);
    }
    return 0;
}

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;

const int MAXN = 100;

struct Edge {
    int v, w;
    Edge(int _v, int _w) {
        v = _v, w = _w;
    }
};

vector<Edge> G[MAXN];
int inDegree[MAXN] = {0};
vector<int> topoOrder;
int ve[MAXN], vl[MAXN];
vector<int> activity[MAXN];

bool topoSort(int n) {
    priority_queue<int, vector<int>, greater<int> > q;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.top();
        q.pop();
        topoOrder.push_back(u);
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            inDegree[v]--;
            if (inDegree[v] == 0) {
                q.push(v);
            }
            if (ve[u] + G[u][i].w > ve[v]) {
                ve[v] = ve[u] + G[u][i].w;
            }
        }
    }
    return (int)topoOrder.size() == n;
}

int getCriticalPath(int n) {
    memset(ve, 0, sizeof(ve));
    if (!topoSort(n)) {
        return -1;
    }
    int maxLength = 0;
    for(int i = 0; i < n; i++) {
        if(ve[i] > maxLength) {
            maxLength = ve[i];
        }
    }
    fill(vl, vl + n, maxLength);

    for (int i = (int)topoOrder.size() - 1; i >= 0; i--) {
        int u = topoOrder[i];
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int w = G[u][j].w;
            if (vl[v] - w < vl[u]) {
                vl[u] = vl[v] - w;
            }
        }
    }

    for (int u = 0; u < n; u++) {
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            int w = G[u][i].w;
            int e = ve[u], l = vl[v] - w;
            if (e == l) {
                activity[u].push_back(v);
            }
        }
    }
    return maxLength;
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        inDegree[v]++;
    }
    if (getCriticalPath(n) == -1) {
        printf("No");
    } else {
        printf("Yes\n");
        for (int i = 0; i < n; i++) {
            sort(activity[i].begin(), activity[i].end());
            for (int j = 0; j < activity[i].size(); j++) {
                printf("%d %d\n", i, activity[i][j]);
            }
        }
    }
    return 0;
}

#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;

const int MAXN = 100;

struct Edge {
    int v, w;
    Edge(int _v, int _w) {
        v = _v, w = _w;
    }
};

vector<Edge> G[MAXN];
int inDegree[MAXN] = {0}, inDegreeOrigin[MAXN] = {0};
vector<int> topoOrder;
int ve[MAXN], vl[MAXN];
vector<int> activity[MAXN];

bool topoSort(int n) {
    priority_queue<int, vector<int>, greater<int> > q;
    for (int i = 0; i < n; i++) {
        if (inDegree[i] == 0) {
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.top();
        q.pop();
        topoOrder.push_back(u);
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            inDegree[v]--;
            if (inDegree[v] == 0) {
                q.push(v);
            }
            if (ve[u] + G[u][i].w > ve[v]) {
                ve[v] = ve[u] + G[u][i].w;
            }
        }
    }
    return (int)topoOrder.size() == n;
}

int getCriticalPath(int n) {
    memset(ve, 0, sizeof(ve));
    if (!topoSort(n)) {
        return -1;
    }
    int maxLength = 0;
    for(int i = 0; i < n; i++) {
        if(ve[i] > maxLength) {
            maxLength = ve[i];
        }
    }
    fill(vl, vl + n, maxLength);

    for (int i = (int)topoOrder.size() - 1; i >= 0; i--) {
        int u = topoOrder[i];
        for (int j = 0; j < G[u].size(); j++) {
            int v = G[u][j].v;
            int w = G[u][j].w;
            if (vl[v] - w < vl[u]) {
                vl[u] = vl[v] - w;
            }
        }
    }

    for (int u = 0; u < n; u++) {
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].v;
            int w = G[u][i].w;
            int e = ve[u], l = vl[v] - w;
            if (e == l) {
                activity[u].push_back(v);
            }
        }
    }
    return maxLength;
}

vector<int> criticalPath;
void printCriticalPath(int u) {
    if(activity[u].size() == 0) {
        criticalPath.push_back(u);
        for(int i = 0; i < criticalPath.size(); i++) {
            printf("%d", criticalPath[i]);
            if(i < criticalPath.size() - 1) {
                printf("->");
            } else {
                printf("\n");
            }
        }
        criticalPath.pop_back();
        return;
    }
    criticalPath.push_back(u);
    sort(activity[u].begin(), activity[u].end());
    for(int i = 0; i < activity[u].size(); i++) {
        printCriticalPath(activity[u][i]);
    }
    criticalPath.pop_back();
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v, w;
    for (int i = 0; i < m; i++) {
        scanf("%d%d%d", &u, &v, &w);
        G[u].push_back(Edge(v, w));
        inDegree[v]++;
        inDegreeOrigin[v]++;
    }
    if (getCriticalPath(n) == -1) {
        printf("No");
    } else {
        printf("Yes\n");
        for(int i = 0; i < n; i++) {
            if(inDegreeOrigin[i] == 0 && activity[i].size() != 0) {
                printCriticalPath(i);
            }
        }
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1926815.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么减少pdf的MB,怎么减少pdf的大小

在数字化时代&#xff0c;pdf文件因其格式稳定、跨平台兼容性强等特点而广受欢迎。然而&#xff0c;随着内容的丰富&#xff0c;pdf文件的大小也日益增大&#xff0c;给文件传输和存储带来了不少困扰。本文将为你介绍多种减小pdf文件大小的方法&#xff0c;帮助你轻松应对这一问…

中间件——Kafka

两个系统各自都有各自要去做的事&#xff0c;所以只能将消息放到一个中间平台&#xff08;中间件&#xff09; Kafka 分布式流媒体平台 程序发消息&#xff0c;程序接收消息 Producer&#xff1a;Producer即生产者&#xff0c;消息的产生者&#xff0c;是消息的入口。 Brok…

Hadoop3:HDFS-存储优化之纠删码

一、集群环境 集群一共5个节点&#xff0c;102/103/104/105/106 二、纠删码原理 1、简介 HDFS默认情况下&#xff0c;一个文件有3个副本&#xff0c;这样提高了数据的可靠性&#xff0c;但也带来了2倍的冗余开销。Hadoop3.x引入了纠删码&#xff0c;采用计算的方式&#x…

Python爬虫速成之路(3):下载图片

hello hello~ &#xff0c;这里是绝命Coding——老白~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;绝命Coding-CSDN博客 &a…

[GXYCTF2019]BabySQli

原题目描述&#xff1a;刚学完sqli&#xff0c;我才知道万能口令这么危险&#xff0c;还好我进行了防护&#xff0c;还用md5哈希了密码&#xff01; 我看到是个黑盒先想着搞一份源码 我dirsearch明明扫到了.git&#xff0c;算了直接注入试试看 随便输入了两个东西&#xff0c…

pico+unity3d项目配置

重点&#xff1a;unity编辑器版本要和pico的sdk要求一致、比如&#xff1a; 对于 Unity 2022.1.14 及以上版本&#xff0c;若同时在项目中使用 URP、Linear 色彩空间、四倍抗锯齿和OpenGL&#xff0c;会出现崩溃。该问题待 Unity 引擎解决。对于 Unity 2022&#xff0c;若同时…

植物神经紊乱?别怕!这些维生素来帮你!

最近收到好多小伙伴的私信&#xff0c;说自己有植物神经紊乱的困扰&#xff0c;不知道该肿么办&#xff1f;别急别急&#xff0c;我给你们来一波大福利&#x1f381;&#xff01;今天就来聊聊植物神经紊乱患者应该补充哪些维生素&#xff0c;让你的身体重回最佳状态&#xff01…

SC.Pandas 03 | 如何使用Pandas分析时间序列数据?

Introduction 前两期我们对Pandas的数据结构和常用的计算方法进行了介绍&#xff0c;在地球科学领域时间序列分析是很重要的一种数据处理方式。 通过理解数据的时间变化特征&#xff0c;我们可以更深入地理解研究对象的演化规律与物理机制。 因此&#xff0c;本期我们就从Pa…

安装cnpm失败

20240714 安装cnpm失败&#xff0c;报错如下&#xff1a; 失败原因&#xff1a; 请求 https://registry.npm.taobao.org 失败&#xff0c;原因&#xff1a;证书已过期 使用以下命令&#xff1a; npm install -g cnpm --registryhttps://registry.npmmirror.com另外&#xff0…

1.33、激活可视化卷积神经网络(matalb)

1、激活可视化卷积神经网络原理及流程 激活可视化&#xff08;Activation Visualization&#xff09;指的是通过可视化神经网络中激活函数的输出&#xff0c;来理解神经网络是如何学习并提取特征的过程。在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;我们可以通过…

【ROS2】中级:RViz-构建自定义 RViz 显示

背景 在 RViz 中有许多类型的数据已经有现有的可视化。然而&#xff0c;如果有一种消息类型尚未有插件来显示它&#xff0c;那么有两种选择可以在 RViz 中查看它。 将消息转换为另一种类型&#xff0c;例如 visualization_msgs/Marker 。编写自定义 RViz 显示。 使用第一个选项…

成为CMake砖家(5): VSCode CMake Tools 插件基本使用

大家好&#xff0c;我是白鱼。 之前提到过&#xff0c;白鱼的主力 编辑器/IDE 是 VSCode&#xff0c; 也提到过使用 CMake Language Support 搭配 dotnet 执行 CMakeLists.txt 语法高亮。 对于阅读 CMakeLists.txt 脚本&#xff0c; 这足够了。 而在 C/C 开发过程中&#xff…

数据结构(单链表(2))

单链表的实现 SList.h 由于代码中已有大量注释&#xff0c;所以该文章主要起到补充说明作用。 &#xfeff;#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h>//定义链表&#xff08;结点&#xff09;的结构typedef int SLTDataType…

MySQL in 太多过慢的 3 种解决方案

文章目录 解决方案一&#xff1a;使用 JOIN 替代 IN示例&#xff1a; 解决方案二&#xff1a;分批处理 IN 子句示例&#xff1a; 解决方案三&#xff1a;使用临时表示例&#xff1a; 总结 &#x1f389;欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)…

力扣刷题之978.最长湍流子数组

题干要求&#xff1a; 给定一个整数数组 arr &#xff0c;返回 arr 的 最大湍流子数组的长度 。 如果比较符号在子数组中的每个相邻元素对之间翻转&#xff0c;则该子数组是 湍流子数组 。 更正式地来说&#xff0c;当 arr 的子数组 A[i], A[i1], ..., A[j] 满足仅满足下列条…

基于用户鼠标移动的规律可以对用户身份进行连续验证的方法

概述 论文地址&#xff1a;https://arxiv.org/abs/2403.03828 本文重点论述了高效可靠的用户身份验证方法在计算机安全领域的重要性。它研究了使用鼠标移动动态作为连续身份验证新方法的可能性。具体来说&#xff0c;本文分析了用户在两个不同游戏场景–团队要塞和聚能桥–中…

关于Kafka Topic分区和Replication分配的策略

文章目录 1. Topic多分区2. 理想的策略3. 实际的策略4. 如何自定义策略 1. Topic多分区 如图&#xff0c;是一个多分区Topic在Kafka集群中可能得分配情况。 P0-RL代表分区0&#xff0c;Leader副本。 这个Topic是3分区2副本的配置。分区尽量均匀分在不同的Broker上&#xff0c…

自动驾驶-2D目标检测

yolo及yolo的变体 anchor boxes (锚框) intersection over union 并集交集 用于计算两个边界框的差异程度 bounding box predictions 边界框预测 non maximum suppression非极大值抑制 为了分离这些边界框并为每个对象获得单个边界框&#xff0c;我们使用IOU。这种获取单…

Ubuntu 安装 XRDP,替代系统自带RDP远程桌面

起因&#xff0c;Ubuntu的自带RDP远程桌面很好用&#xff0c;但很傻卵&#xff0c;必须登录。 而设置了自动登录也不能解开KEYRING&#xff0c;必须必须必须用GUI手动登录。 &#xff08;我远程我用头给你坐机子面前开显示器先登录&#xff1f;&#xff1f;&#xff09; 比起VN…

vue3 快速入门 (二) : 实现第一个Vue网页,并在手机上浏览

1. 最简单的一个VUE网页 首先&#xff0c;我们可以看我的这篇文章 : vue3 快速入门 (一) : 环境配置与搭建 完成环境搭建。 接着就可以来实现我们的第一个Vue网页了。 本文环境 Vue版本 : 3.4.29Node.js版本 : v20.15.0系统 : Windows11 64位IDE : VsCode 1.1 基础模板 vu…