PTA Data Structure Problem Set Week 8 -- Graphs (Part 3)

发表于 2020-08-21 03:45 1224 字 7 min read

cos avatar

cos

FE / ACG / 手工 / 深色模式强迫症 / INFP / 兴趣广泛养两只猫的老宅女 / remote

剑指offer day31 数学(困难)剑指offer day30 分治算法(困难)剑指offer day29 动态规划(困难)剑指offer day28 搜索与回溯算法(困难)剑指offer day27 栈与队列(困难)剑指offer day26 字符串(中等)剑指offer day25 模拟(中等)剑指offer day24 数学(中等)剑指offer day23 数学(简单)剑指offer day22 位运算(中等)剑指offer day21 位运算(简单)剑指offer day20 分治算法(中等)剑指offer day19 搜索与回溯算法(中等)剑指offer day18 搜索与回溯算法(中等)剑指offer day17 排序(中等)剑指offer day16 排序(简单)剑指offer day15 搜索与回溯算法(中等)剑指offer day14 搜索与回溯算法(中等)剑指offer day13 双指针(简单)剑指offer day12 双指针(简单)剑指offer day11 双指针(简单)剑指offer day10 动态规划(中等)剑指offer day9 动态规划(中等)剑指offer day8 动态规划(简单)剑指offer day7 搜索与回溯算法(简单)剑指offer day6 搜索与回溯算法(简单)剑指offer day5 查找算法(中等)剑指offer day4 查找算法(简单)剑指offer day3 字符串(简单)剑指offer day2 链表(简单)剑指offer day1 栈与队列(简单)冲刺春招-精选笔面试66题大通关day22冲刺春招-精选笔面试66题大通关day21冲刺春招-精选笔面试66题大通关day20冲刺春招-精选笔面试66题大通关day19冲刺春招-精选笔面试66题大通关18冲刺春招-精选笔面试66题大通关17冲刺春招-精选笔面试66题大通关16冲刺春招-精选笔面试66题大通关day15冲刺春招-精选笔面试66题大通关day14冲刺春招-精选笔面试66题大通关day13冲刺春招-精选笔面试66题大通关day12冲刺春招-精选笔面试66题大通关day11冲刺春招-精选笔面试66题大通关day10冲刺春招-精选笔面试66题大通关day9冲刺春招-精选笔面试66题大通关day8冲刺春招-精选笔面试66题大通关day7冲刺春招-精选笔面试66题大通关day6冲刺春招-精选笔面试66题大通关day5冲刺春招-精选笔面试66题大通关day4冲刺春招-精选笔面试66题大通关day3冲刺春招-精选笔面试66题大通关day2冲刺春招-精选笔面试66题大通关day12021 Fall PAT Grade B Real Exam Solutions and Post-Contest SummaryPAT Grade B Practice Reflections and Pitfall SummaryPTA Data Structures Problem Set Week 3 - Planting Trees (Binary Trees, etc.)PTA Data Structure Problem Set Week 11 -- Hash SearchPTA Data Structure Problem Set Week 10 -- Sorting (Part 2)PTA Data Structure Problem Set Week 9 -- Sorting (Part 1)PTA Data Structure Problem Set Week 8 -- Graphs (Part 3)PTA Data Structure Problem Set Week 7 -- Graphs (Part 2)PTA Data Structure Problem Set Week 6 -- Graphs (Part 1)PTA Data Structures Problem Set Week 5 - Heaps & Huffman Trees & Union-FindPTA Data Structures Problem Set Week 4 - Binary Search Trees & AVL TreesPTA Data Structures Problem Set Week 2 - Linear StructuresPTA Data Structures Problem Set Week 1 - Maximum Subsequence Sum Algorithm & Binary SearchMOOC ZJU Data Structures After-Class Problems Record - PTA Data Structures Problem Set (Complete)2020 Lanqiao Cup Provincial Mock Contest Problem Record
该文章整理了图论相关题目的解题思路与代码实现,涵盖最小生成树(Kruskal算法)、拓扑排序及其在求项目最早完成时间与关键活动中的应用。通过分析题目特点,总结了从基础到进阶的解题方法,并指出关键活动问题在实现时易出现逻辑错误,需仔细调试。

This article has been machine-translated from Chinese. The translation may contain inaccuracies or awkward phrasing. If in doubt, please refer to the original Chinese version.

@[TOC](Table of Contents) Problem Set Master Index Study reference blogs: Solving Minimum Spanning Tree Problems (Kruskal Algorithm & Prim Algorithm), Data Structure Study Notes <8> Sorting

08-Graph 7 Highway Connecting All Villages (30 pts)

Problem link

A very straightforward minimum spanning tree problem, but the code is somewhat lengthy. Optional — write it if you have time.

Problem Summary

Given the highway construction costs between all villages, calculate the minimum cost to connect all villages. A classic minimum spanning tree template problem, solvable with Kruskal’s algorithm.

Code

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxm = 3030;
const int maxn = 1005;
const int inf = 0x3f3f3f3f;
int fa[maxn];
int N,M;//顶点数 边数
struct edge {
    int u,v,w;
    bool operator<(const edge& a) const {
        return w < a.w;
    }
} E[maxm];//最大边数maxm
int find(int x) {
    return fa[x] == -1 ? x : fa[x] = find(fa[x]);
}
int Kruskal() {
    for(int i = 0; i <= N; ++i) fa[i] = -1;
    int ans,cnt;
    ans = cnt = 0;
    sort(E,E+M);
    for(int i = 0; i < M; ++i) {
        int x = find(E[i].u);
        int y = find(E[i].v);
        if(x != y) {
            fa[x] = y;
            ans += E[i].w;
            cnt++;
        }
        if(cnt == N-1) break;
    }
    if(cnt != N-1) return -1;
    else return ans;
}
int main(){
    cin >> N >> M;
    for(int i = 0; i < M; ++i) {
        cin >> E[i].u >> E[i].v >> E[i].w;
    }
    cout << Kruskal() << endl;
    return 0;
}

Test Cases

Test cases are as follows:

在这里插入图片描述

08-Graph 8 How Long Does It Take (25 pts)

Problem link

A variation of topological sort. The program is not too complex, so it’s recommended to give it a try.

Problem Summary

Given a project with N activity checkpoints (numbered 0 to N-1) and M activities, where each of the M lines contains three integers representing the start checkpoint number, end checkpoint number, and duration, find the earliest completion time of the project.

Approach

Compute the earliest completion time for each checkpoint during topological sorting. The earliest completion time for the entire project is the maximum among all checkpoint earliest completion times.

Code

// 08-图8 How Long Does It Take (25分)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
#define div 1000000007
const int maxn = 105;
const int inf  = 0x3f3f3f;
int N,M,ans;
int edge[maxn][maxn];//所有活动
int mint[maxn];//到每个活动检查点的最短时间
int In[maxn];//每个活动检查点的入度
void init() {
    memset(edge, -1, sizeof(edge));
    memset(mint, 0, sizeof(mint));
    memset(In, 0, sizeof(In));
    ans = 0;
}
bool Topsort() {//拓扑排序
    queue<int> q;
    for(int i = 0; i < N; ++i) {
        if(In[i] == 0) {
            mint[i] = 0;//若为起点,则最短时间当然为0
            q.push(i);
        }
    }
    int cnt = 0;
    while(!q.empty()) {
        int v = q.front();
        q.pop();
        cnt++;
        for(int i = 0; i < N; ++i) {
            if(v == i || edge[v][i] == -1) continue;//检查以v为起点的所有边
            In[i]--;
            if(mint[i] < mint[v] + edge[v][i])
                mint[i] = mint[v] + edge[v][i];
            if(In[i] == 0) q.push(i);
        }
    }
    if(cnt != N) return false;
    else return true;
}
int main(){
    ios::sync_with_stdio(false);
    cin >> N >> M;
    init();
    for(int i = 0; i < M; ++i) {
        int u,v,w;
        cin >> u >> v >> w;
        edge[u][v] = w;
        In[v]++;
    }
    if(Topsort()) {
        for(int i = 0; i < N; ++i) {
            if(mint[i] > ans) ans = mint[i];
        }
        cout << ans << endl;
    } else cout << "Impossible" << endl;
    return 0;
}

Test Cases

在这里插入图片描述

08-Graph 9 Critical Activities (30 pts)

Problem link

After listening to the lecture, the approach for this problem should be fairly clear. You just need to add some content on top of the previous problem’s program. However, the code is still somewhat lengthy, so proceed based on your available time. Enter with caution.

Problem Summary

Similar to the previous problem, but in addition to the earliest completion time, the latest completion time is also required to derive the slack time. Finally, output whether the task can be completed, and if so, output the critical activities (activities with no slack time).

Code

// 08-图8 How Long Does It Take (25分)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
#define div 1000000007
const int maxn = 105;
const int inf  = 0x3f3f3f;
int N,M,ans,last;
int edge[maxn][maxn];//所有活动
int mint[maxn];//到每个活动检查点的最短时间
int maxt[maxn];//到每个活动检查点的最长时间
int In[maxn];//每个活动检查点的入度
int Out[maxn];//每个活动检查点的出度
void init() {
    memset(edge, -1, sizeof(edge));
    memset(mint, 0, sizeof(mint));
    memset(maxt, 0x3f, sizeof(maxt));
    memset(In, 0, sizeof(In));
    memset(Out, 0, sizeof(Out));
    ans = last = 0;
}
bool Get_Mint() {
    queue<int> q;
    for(int i = 1; i <= N; ++i) {
        if(In[i] == 0)
            q.push(i);
    }
    int cnt = 0;
    while(!q.empty()) {
        int v = q.front();
        q.pop();
        cnt++;
        for(int i = 1; i <= N; ++i) {
            if(edge[v][i] == -1) continue;
            In[i]--;
            //<v,i>有有向边
            mint[i] = max(mint[i], mint[v] + edge[v][i]);
            if(In[i] == 0)
                q.push(i);
        }
    }
    if(cnt != N) return false;
    else return true;
}

void Get_Maxt() {
    queue<int> q;
    maxt[last] = ans;
    for(int v = 1; v <= N; ++v) {
        if(Out[v] == 0) {
            q.push(v);
            Out[v] = -1;
        }
    }
    while(!q.empty()) {
        int v = q.front();
        q.pop();
        for(int i = 1; i <= N; ++i) {
            if(edge[i][v] == -1) continue;
            Out[i]--;
            //<i,v>有有向边
            maxt[i] = min(maxt[i], maxt[v] - edge[i][v]);
            if(Out[i] == 0) {
                q.push(i);
                Out[i] = -1;
            }
        }
    }
}
int main(){
    cin >> N >> M;
    init();
    for(int i = 1; i <= M; ++i) {
        int u,v,w;
        cin >> u >> v >> w;
        edge[u][v] = w;
        In[v]++;
        Out[u]++;
    }
    if(Get_Mint()) {
        for(int i = 1; i <= N; ++i) {
            if(ans < mint[i]) {
                ans = mint[i];
                last = i;
            }
        }
        cout << ans << endl;
        Get_Maxt();
        for(int i = 1; i <= N; ++i) {
            for(int j = N; j >= 1; --j) {
                if(edge[i][j] != -1 && edge[i][j] == maxt[j] - mint[i]) {
                    cout << i << "->" << j << endl;
                }
            }
        }
    } else cout << 0 << endl;
    return 0;
}

Test Cases

Kept getting WA on test cases 2 and 5… finally found out two lines of code were swapped qwq

在这里插入图片描述

喜欢的话,留下你的评论吧~

© 2020 - 2026 cos @cosine
Powered by theme astro-koharu · Inspired by Shoka