问题 A: 割点与桥

时间限制: 1 Sec  内存限制: 5 MB
提交: 475  解决: 34
提交 状态 算法问答

题目描述

给出一个无向连通图,找到所有的割点和桥

输入

第一行:点的个数,如果点个数是n,他们的编号为0 ~ n-1

余下的行:每行代表一条边,如“0 2”代表顶点0和顶点2有一条边 (一条边只出现一次,如出现“0 2”则不会出现“2 0”)

输出

这次需要大家先输出一个字符串,它是“我已阅读关于抄袭的说明”的汉语拼音.输出此行的提交我们将认为已经完全阅读并了解了“关于抄袭的说明”公告.

所有的割点和所有的桥,先输出割点再输出桥

割点按编号升序排列,桥按边的升序排列,如“0 2”小于“0 3”,“1 5”小于“2 3”(边的输出和排列总是把小顶点放前面,所以输出总是“0 2”而非“2 0”)

样例输入

5
1 2
1 3
2 4
0 1
0 2

样例输出

wo yi yue du guan yu chao xi de shuo ming
1
2
1 3
2 4

提示

两个算法的伪代码书上都有了,就不多说了。

这个题比较坑的地方是空间复杂度,开始保存图一直使用的set<int>,一直不过,改成vector<int>就过了

本题中,为了节省空间,我尽量使用了new,在染色节点的时候,我直接使用了discovertime来表示,当discovertime==0时表示节点未访问,discovertime<0表示正在访问,discovertime>0时表示访问结束。所以在DFS刚访问节点设置discovertime时,我将discovertime设置为-time,结束时去绝对值。

答案

#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;//找割点
void DFS_find_cutvertex(vector<int>* g, int point, int time, pair<int, int>* times,vector<int> & result,int& treenum,int parent) {++time;//在访问节点是,将back设为当前时间times[point].second = time * -1;times[point].first = time;//节点染成灰色for (auto i = g[point].begin(); i!= g[point].end(); i++) {//到此时,此时i表示需要遍历的下一个邻居节点int y = *i;if (times[*i].second == 0) {if (point == 0) treenum++;DFS_find_cutvertex(g, *i, time, times,result,treenum,point);//判断是否为割点if (times[*i].first >= abs(times[point].second) && point != 0)result.emplace_back(point);times[point].first = min(times[point].first, times[*i].first);}else {//正在被访问,这能代表BF的边?if (times[*i].second < 0 && *i != parent) {times[point].first = min(times[point].first, abs(times[*i].second));}}}//节点染成黑色times[point].second = abs(times[point].second);
}//找桥,对寻找割点的程序简单修改
void DFS_find_bridge(vector<int>* g, int point, int time, pair<int, int>* times, vector<pair<int,int>> & result,int parent) {++time;//当discovertime为负数时,表示正在被访问times[point].second = time * -1;times[point].first = time;for (auto i = g[point].begin(); i != g[point].end(); i++) {if (times[*i].second == 0) {DFS_find_bridge(g, *i, time, times, result,point);times[point].first = min(times[point].first, times[*i].first);if (times[*i].first > abs(times[point].second)) {//保持结果中的边小的点在前if(point < *i) result.emplace_back(pair<int, int>(point, *i));else result.emplace_back(pair<int, int>(*i,point));}}else {if (times[*i].second < 0 && *i != parent) {times[point].first = min(times[point].first, abs(times[*i].second));}}}//节点染成黑色times[point].second =abs(times[point].second);
}int main()
{int point_num = 0;cin >> point_num;//times的first和second用来存放寻找割点时保存的back值和discovertimepair<int, int>* times = new pair<int, int>[point_num];//每个点能到达的其他点vector<int>* g = new vector<int>[point_num];int in = 0;int out = 0;while (cin >> in && cin >> out) {g[in].emplace_back(out);g[out].emplace_back(in);}//DFS寻找割点int time = 0;vector<int> result;int treenum = 0;DFS_find_cutvertex(g,0,time, times, result,treenum,-1);if (treenum >= 2)result.emplace_back(0);sort(result.begin(),result.end());//将节点全部染成白色.时间重置for (auto i = 0; i < point_num; i++) {times[i].first = 0;times[i].second = 0;}    //DFS寻找桥int time2 = 0;vector<pair<int,int>> result2;DFS_find_bridge(g, 0, time2, times, result2, -1);sort(result2.begin(), result2.end());cout << "wo yi yue du guan yu chao xi de shuo ming" << endl;for (auto i = 0 ;i<result.size();i++)cout << int(result[i]) << endl;for (auto i = 0; i < result2.size(); i++) {cout << int(result2[i].first) << " " << int(result2[i].second) << endl;}delete []times;delete []g;return 0;
}

问题 B: 任务调度问题

时间限制: 1 Sec  内存限制: 5 MB
提交: 168  解决: 39
提交 状态 算法问答

题目描述

请大家在做oj题之前,仔细阅读关于抄袭的说明http://www.bigoh.net/JudgeOnline/.

算法助教实在是太忙了,每天有n个事情要做,但他觉得自己一件一件的做实在是太蠢了,所以想找一些班上的同学来帮忙一块做这些事。

在分配任务的过程中他发现,这n个任务中有一些任务的开始需要依赖另一些任务的完成,例如,当只有先批改完算法作业(记为事件A),才能给大家登记作业成绩(记为事件B),这时我们就可称事件B依赖于事件A。机智的他利用了算法课上的知识,采用有向图中的节点来表示这些事件,并且利用图中的边来表示这些事件的依赖关系,例如,当事件B依赖于事件A时,图中就存在一条由B指向A的边。助教还对这样的有向图进行了升级,用节点的权值表示完成每个事件所需要的时间。

然而,随后他发现,由于图中依赖关系的存在,即使他利用庞大的关系网能找来无穷多个同学帮他做这些事,完成所有事件的最短时间也是确定的。那么问题来了,助教每天要花多少时间来处理这n个事情呢?这时,助教想起了算法课上学到的关键路径的定义似乎能够帮他解决这个问题。聪明的同学们,你们能告诉助教他即使找到帮手,每天做完这n个事情最短也需要花多长时间吗?

(善良的助教已经帮你们把这些事情建模成有向图,如输入所示。)

输入

第一行为图中的顶点个数n

第二行至第n+1行为每个顶点代表的事件编号(事件编号为1至n)及完成该事件所需的时间。 如,“1 50”代表完成事件1需要50个单位时间。

余下的行中,每一行表示一个依赖关系,例如,“1 3” 表示事件1的完成依赖于事件3的完成。

输出

这次依旧需要大家输出一行字符串,它还是“我已阅读关于抄袭的说明”的英文翻译,即:"I have read the rules about plagiarism punishment"。输出此行的提交我们将认为已经完全阅读并了解了“关于抄袭的说明”公告并同意关于抄袭的惩罚措施。

第二行输出完成所有这n个任务所需最短的执行时间。

样例输入

9
1 10
2 6
3 5
4 1
5 2
6 3
7 4
8 9
9 1
1 9
2 1
2 8
3 5
3 6
3 7
4 2
4 3
5 9
6 9
7 9
8 9

样例输出

I have read the rules about plagiarism punishment
18

提示

如果这些事情出现了循环依赖,则助教永远也不可能做完这些事(好惨 TAT)。所以你可以大胆假定,助教要做的这些事情中并不存在循环依赖,也就是说,输入的图一定是一个有向无环图。

答案

算法同样在书上有,就不多说了。

这里需要注意的就是在DFS上需要加wapper,遍历每个节点,找出最大的最早结束时间,注意,在遍历完一个节点后,不要清除visited和时间内容,这样遍历下一个节点时能减少工作量。

具体各对象的实现就看代码吧

#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;//g表示图,point表示遍历开始节点,times表示各点最早开始结束时间,visited表示节点访问状态,result表示最大的最早结束时间
void DFS_critical_path(vector<int>* g, int point, pair<int, int>* times, vector<int>& visited, vector<int>& cost) {visited[point] = 1;times[point].first = 0;for (auto i = g[point].begin(); i != g[point].end(); i++) {if (visited[*i] == 0) {DFS_critical_path(g, *i, times,visited,cost);if (times[*i].second >= times[point].first) {times[point].first = times[*i].second;}}else {if (times[*i].second >= times[point].first) {times[point].first = times[*i].second;}}}//节点染成黑色times[point].second = times[point].first + cost[point];visited[point] = 2;
}int main()
{int point_num = 10;cin >> point_num;vector<int> cost(point_num,0);int num = 0;int c = 0;//v[i].first表示最早开始时间,v[i].second表示最早结束时间pair<int, int>* times = new pair<int, int>[point_num];//visited[i] == 0表示节点未访问,visited == 1 表示节点正在访问,visited == 2表示访问结束vector<int> visited(point_num, 0);////path[i] == 0表示i不是关键路径,path[i] == 1表示i是关键路径//vector<int> path(point_num, 0);//获取每个事件的花费for (int i = 0; i < point_num; i++) {cin >> num;cin >> c;cost[i] = c;}//将A依赖于B表示成图中有B到A的单向边,g[i]表示点i能到达的所有点vector<int>* g = new vector<int>[point_num];while (cin >> num && cin >> c) {//输入是从1开始,但数组索引是从0开始g[num-1].emplace_back(c-1);}/*cost = {10,6,5,1,2,3,4,9,1,20};g[0] = {8};g[1] = {0,7};g[2] = {4,5,6};g[3] = {1,2};g[4] = {8};g[5] = {8};g[6] = {8};g[7] = {8};g[8] = {};g[9] = { 7 };begin[3] = 1;begin[9] = 1;*///DFS遍历,从所有节点都做一遍DFS,找出最大的最晚结束时间int result = 0;for (int i = 0; i < point_num; i++) {DFS_critical_path(g, i, times, visited, cost);if (times[i].second > result)result = times[i].second;}cout << "I have read the rules about plagiarism punishment" << endl;cout << result << endl;delete[]times;delete[]g;
}

转载于:https://www.cnblogs.com/likaiming/p/9053405.html

南大算法设计与分析课程OJ答案代码(5)--割点与桥和任务调度问题相关推荐

  1. 算法设计与分析课程的时间空间复杂度

    算法设计与分析课程的时间空间复杂度: 总结 算法 时间复杂度 空间复杂度 说明 Hanoi $ O(2^n) $ $ O(n) $ 递归使用 会场安排问题 \(O(nlogn)\) \(O(n)\) ...

  2. 计算机算法课程论文设计与实现,算法设计与分析课程论文

    算法设计与分析课程论文 "卓越工程师教育培养计划"(简称卓越计划)旨在培养一批创新能力强.适应经济社会发展需要的高质量工程技术人才.在南通大学计算机科学与技术学院制定的软件工程专业 ...

  3. 算法设计与分析课程复习笔记11——单源最短路径

    算法设计与分析课程复习笔记11--单源最短路径 单源最短路径 最短路径问题 输入:有权有向图G=(V,E) 路径p={ v 0 , v 1 , . . . , v k v_0, v_1, . . . ...

  4. 深大算法设计与分析实验二——分治法求最近点对问题

    源代码: 深大算法设计与分析实验二--分治法求最近点对问题代码-C/C++文档类资源-CSDN下载 目录 实验问题 一.实验目的: 二.内容: 三.算法思想提示 产生不重复的随机点算法: 蛮力算法: ...

  5. 算法设计与分析 课程设计之N皇后问题

    题目 N皇后回溯法求解空间 目的要求 目的: 1.用学到的书本知识解决实际问题的能力: 2.锻炼实际工作所需要的动手能力: 3.加强对数据结构和算法的应用: 4.锻炼自己以科学理论和工程上能力的技术, ...

  6. 算法设计和分析课程设计报告

    文章目录 1. 题目 2. 目的 3. 内容 4. 需求分析 5. 逻辑结构设计 6.算法详细设计 7.编码与调试 8. 算法改进,优化方法 10.总结,心得体会 课程设计报告要求 1. 题目 01背 ...

  7. 【分治法】中位数问题和Gray码问题——武汉理工大学算法设计与分析课程实验

    1. 中位数问题 « 问题描述 设X[ 0 : n - 1]和Y[ 0 : n – 1 ]为两个数组,每个数组中含有n个已排好序的数.找出X和Y的2n个数的中位数. « 编程任务 利用分治策略试设计一 ...

  8. 【动态规划】最大K乘积问题和游艇租用问题——武汉理工大学算法设计与分析课程实验

    1.  最大K乘积问题 « 问题描述 设I是一个n位十进制整数.如果将I划分为k段,则可得到k个整数.这k个整数的乘积称为I的一个k乘积.试设计一个算法,对于给定的I和k,求出I的最大k乘积. 例如十 ...

  9. 算法设计与分析基础 课后答案

    Introduction to the Design and Analysis of Algorithms 3rd Edition (算法分析设计基础Anany Levitin ,潘彦)第三版课后答案 ...

最新文章

  1. 安装java的rpm_Centos7使用rpm命令安装java
  2. 五种JSP页面跳转方法详解
  3. 系统变量file.encoding对Java的运行影响有多大?(转)good
  4. Windows中使用PowerShell+任务计划程序实现Mysql数据之间的同步
  5. zigbee物联网模块市场:LTE标准Cat.1和nbiot无线通信模块差异
  6. c++和java哪个难_为什么说C语言比Java难?
  7. TimesTen数据库使用之点滴(1)
  8. html 图片轮播渐变,简单的jquery图片轮播渐变
  9. 网络七层协议,五层协议概述
  10. 【wps】wps怎样删除中间的一页?
  11. CSS动画-Animation
  12. eclipse使用maven新建类目录时,提示The folder is already a source folder
  13. 基于MATLAB的数字信号处理(5) FIR数字滤波器设计及软件实现
  14. plot指定线段形状和颜色_形状和颜色背后的心理学
  15. 苹果电脑App Store下载失败
  16. Dango搭建个人博客:前言
  17. ES5和ES6的类,静态方法,继承实现代码
  18. B站网页视频加速设置
  19. java lang ClassCastException java lang Integer cannot be ca
  20. 前端面试题(附答案)完善中……

热门文章

  1. Java学习笔记---字符类型
  2. Styling with the DataGridColumnStyle
  3. 模型数据的保存和读取
  4. php中getdistance函数_php计算两个经纬度地点之间的距离
  5. python中的repr是什么意思_Python中__repr__和__str__区别详解
  6. android receiver 通知,android – 来自BroadcastReceiver的呼叫通知
  7. 连接状态_TCP 连接状态及相关命令学习
  8. sar sensor传感器的作用_传感器攻防战-惯导IMU
  9. python怎么做彩票概率_用Python一次性把论文作图与数据处理全部搞定!
  10. cmake java_JNI系列之AS支持CMake了