第十一章 图论

ops/2025/1/20 2:30:20/
#include <iostream> 
#include <cstdio>
#include <vector>using namespace std;const int MAXN = 1000;vector<int> graph[MAXN];    //用向量存储邻接表中的每个点及其连接的的其他点int main(){return 0;
}
#include <iostream> 
#include <cstdio>
#include <vector>using namespace std;const int MAXN = 1000;int father[MAXN];
int height[MAXN];  //查找-路径压缩 void Initial(int n){for(int i = 0; i < n; ++i){father[i] = i;
// 		height[i] = 0;  查找-路径压缩 }return;
}int Find(int x){if(x != father[x]){return Find(father[x]);
//		father[x] = Find(father[x]);  查找-路径压缩 }return father[x];
}void Union(int x,int y){x = Find(x);y = Find(y);if(x != y){father[x] = y; 
/*	查找-路由聚合 if(height[x] < height[y]){father[x] = y;}else if(height[x] > height[y]){father[y] = x;}else{father[y] = x;height[x]++;}								*/ }
}int main(){return 0;
}

/*
* 题目名称:连通图
* 题目来源:吉林大学复试上机题
* 题目链接:http://t.cn/AiO77VoA
* 代码作者:杨泽邦(炉灰)
*/#include <iostream>
#include <cstdio>using namespace std;const int MAXN = 1000 + 10;int father[MAXN];                               //父亲结点
int height[MAXN];                               //结点高度void Initial(int n) {                           //初始化for (int i = 0; i <= n; i++) {father[i] = i;                          //每个结点的父亲为自己height[i] = 0;                          //每个结点的高度为零}
}int Find(int x) {                               //查找根结点if (x != father[x]) {                       //路径压缩father[x] = Find(father[x]);}return father[x];
}void Union(int x, int y) {                      //合并集合x = Find(x);y = Find(y);if (x != y) {                               //矮树作为高树的子树if (height[x] < height[y]) {father[x] = y;} else if (height[y] < height[x]) {father[y] = x;} else {father[y] = x;height[x]++;}}return ;
}int main() {int n, m;while (scanf("%d%d", &n, &m) != EOF) {if (n == 0 && m == 0) {break;}Initial(n);                             //初始化while (m--) {int x, y;scanf("%d", &x);scanf("%d", &y);Union(x, y);                        //合并集合}int component = 0;                      //连通分量for (int i = 1; i <= n; i++) {if (Find(i) == i) {                 //集合数目component++;}}if (component == 1) {printf("YES\n");} else {printf("NO\n");}}return 0;
}

/*
* 题目名称:还是畅通工程
* 题目来源:浙江大学复试上机题
* 题目链接:http://t.cn/AiWud0C6
* 代码作者:杨泽邦(炉灰)
*/#include <iostream>
#include <cstdio>
#include <algorithm>using namespace std;const int MAXN = 100 + 10;struct Edge {int from;                           //边的起点int to;                             //边的终点int length;                         //边的长度bool operator< (const Edge& e) const {return length < e.length;}
};Edge edge[MAXN * MAXN];                 //边集
int father[MAXN];                       //父亲结点
int height[MAXN];                       //结点高度void Initial(int n) {                   //初始化for (int i = 0; i <= n; i++) {father[i] = i;height[i] = 0;}
}int Find(int x) {                       //查找根结点if (x != father[x]) {father[x] = Find(father[x]);}return father[x];
}void Union(int x, int y) {              //合并集合x = Find(x);y = Find(y);if (x != y) {if (height[x] < height[y]) {father[x] = y;} else if (height[y] < height[x]) {father[y] = x;} else {father[y] = x;height[x]++;}}return ;
}int Kruskal(int n, int edgeNumber) {Initial(n);sort(edge, edge + edgeNumber);      //按权值排序int sum = 0;for (int i = 0; i < edgeNumber; ++i) {Edge current = edge[i];if (Find(current.from) != Find(current.to)) {Union(current.from, current.to);sum += current.length;}}return sum;
}int main() {int n;while (scanf("%d", &n) != EOF) {if (n == 0) {break;}int edgeNumber = n * (n - 1) / 2;for (int i = 0; i < edgeNumber; ++i) {scanf("%d%d%d", &edge[i].from, &edge[i].to, &edge[i].length);}int answer = Kruskal(n, edgeNumber);printf("%d\n", answer);}return 0;
}

//题目名称:畅通工程续,未优化
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
#include <climits>using namespace std;const int MAXN = 200;
const int INF = INT_MAX;                        //无穷设为很大的数struct Edge {int to;                                     //终点int length;                                 //长度Edge(int t, int l): to(t), length(l) {}
};vector<Edge> graph[MAXN];                       //邻接表实现的图
int dis[MAXN];                          //源点到各点最短距离
bool visit[MAXN];void Dijkstra(int start,int n) {memset(visit, false, sizeof(visit));fill(dis, dis + n, INF); dis[start] = 0;for(int i = 0; i < n; ++i){int u = -1;for(int j = 0; j < n; ++j){if(visit[j]){continue;}if(u = -1 || dis[j] < dis[u]){u = j;}}for(int j = 0; j < graph[u].size(); ++j){int v = graph[u][j].to;int d = graph[u][j].length;if(dis[u] + d < dis[v]){dis[v] = dis[u] + d;}}visit[u] = true;}return ;
}int main() {int n, m;while (scanf("%d%d", &n, &m) != EOF) {memset(graph, 0, sizeof(graph));            //图初始化while (m--) {int from, to, length;scanf("%d%d%d", &from, &to, &length);graph[from].push_back(Edge(to, length));graph[to].push_back(Edge(from, length));}int start;int terminal;                        //起点与终点scanf("%d%d", &start, &terminal);Dijkstra(start,n);if (dis[terminal] == INF) {         //终点不可达dis[terminal] = -1;}printf("%d\n", dis[terminal]);}return 0;
}
/*
* 题目名称:畅通工程续
* 题目来源:HDU 1874
* 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1874
* 代码作者:杨泽邦(炉灰)
*/#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <queue>
#include <climits>using namespace std;const int MAXN = 200 + 10;
const int INF = INT_MAX;                        //无穷设为很大的数struct Edge {int to;                                     //终点int length;                                 //长度Edge(int t, int l): to(t), length(l) {}
};//增加优先队列对应点的结构体
struct Point {int number;                                 //点的编号int distance;                               //源点到该点距离Point(int n, int d): number(n), distance(d) {}bool operator< (const Point& p) const {return distance > p.distance;           //距离小的优先级高}
};vector<Edge> graph[MAXN];                       //邻接表实现的图
int minDistance[MAXN];                          //源点到各点最短距离,minDistance替换了dis
//删除visit数组,用优先队列去存储在集合t中的点void Dijkstra(int start) {minDistance[start] = 0;priority_queue<Point> myPriorityQueue;      //定义优先级队列,并把优先级队列起点压入myPriorityQueue.push(Point(start, minDistance[start]));while (!myPriorityQueue.empty()) {          //增加以下语句int u = myPriorityQueue.top().number;   //离源点最近的点myPriorityQueue.pop();                  //删除部分语句for (int i = 0; i < graph[u].size(); ++i) {int v = graph[u][i].to;int d = graph[u][i].length;if (minDistance[v] > minDistance[u] + d) {minDistance[v] = minDistance[u] + d;myPriorityQueue.push(Point(v, minDistance[v]));}}}return ;
}int main() {int n, m;while (scanf("%d%d", &n, &m) != EOF) {memset(graph, 0, sizeof(graph));            //图初始化fill(minDistance, minDistance + n, INF);    //距离初始化为无穷while (m--) {int from, to, length;scanf("%d%d%d", &from, &to, &length);graph[from].push_back(Edge(to, length));graph[to].push_back(Edge(from, length));}int start, terminal;                        //起点与终点scanf("%d%d", &start, &terminal);Dijkstra(start);if (minDistance[terminal] == INF) {         //终点不可达minDistance[terminal] = -1;}printf("%d\n", minDistance[terminal]);}return 0;
}

/*
* 题目名称:确定比赛名次
* 题目来源:HDU 1285
* 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1285
* 代码作者:杨泽邦(炉灰)
*/#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <functional>using namespace std;const int MAXN = 500 + 10;vector<int> graph[MAXN];
int inDegree[MAXN];                         //入度vector<int> TopologicalSort(int n) {vector<int> topology;                   //拓扑序列priority_queue<int, vector<int>, greater<int> > node;for (int i = 1; i <= n; ++i) {if (inDegree[i] == 0) {node.push(i);}}while (!node.empty()) {int u = node.top();node.pop();topology.push_back(u);              //加入拓扑序列for (int i = 0; i < graph[u].size(); ++i) {int v = graph[u][i];inDegree[v]--;                  //后继结点入度减一if (inDegree[v] == 0) {node.push(v);}}}return topology;
}int main() {int n, m;while (scanf("%d%d", &n, &m) != EOF) {memset(graph, 0, sizeof(graph));memset(inDegree, 0, sizeof(inDegree));while (m--) {int from, to;scanf("%d%d", &from, &to);graph[from].push_back(to);inDegree[to]++;}vector<int> answer = TopologicalSort(n);for (int i = 0; i < answer.size(); ++i) {if (i == 0) {printf("%d", answer[i]);} else {printf(" %d", answer[i]);}}printf("\n");}return 0;
}

题目描述:

阿里这学期修了计算机组织和架构课程。他了解到指令之间可能存在依赖关系,比如WAR(读后写)、WAW、RAW。
如果两个指令之间的距离小于安全距离,则会导致危险,从而可能导致错误的结果。因此,我们需要设计特殊的电路来消除危险。
然而,解决这个问题最简单的方法是添加气泡(无用操作),这意味着浪费时间来确保两条指令之间的距离不小于安全距离。两条指令之间的距离的定义是它们开始时间之间的差异。

现在我们有很多指令,我们知道指令之间的依赖关系和安全距离。我们还有一个非常强大的CPU,具有无限数量的内核,因此您可以同时运行任意数量的指令,而且CPU速度非常快,完成任何指令只需花费1ns。
你的工作是重新排列指令,这样CPU就可以在最短的时间内完成所有指令。

输入:

输入由几个测试用例组成。
第一行有两个整数N,M(N<=1000,M<=10000),表示有N个指令和M个依赖关系。
以下M行,每行包含三个整数X、Y、Z,表示X和Y之间的安全距离为Z,Y应在X之后运行。指令的编号从0到N-1。

输出: 

打印一个整数,即CPU运行所需的最短时间。

/*
* 题目名称:Instrction Arrangement
* 题目来源:HDU 4109
* 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4109
* 代码作者:杨泽邦(炉灰)
*/#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <cstring>
#include <climits>using namespace std;const int MAXN = 1000 + 10;
const int INF = INT_MAX;struct Edge {int to;                                     //终点int length;                                 //长度Edge(int t, int l): to(t), length(l) {}
};vector<Edge> graph[MAXN];
int earliest[MAXN];                             //最早完成时间
int latest[MAXN];                               //最晚完成时间
int inDegree[MAXN];                             //入度int CriticalPath(int n) {vector<int> topology;                       //拓扑序列queue<int> node;for (int i = 0; i < n; ++i) {if (inDegree[i] == 0) {node.push(i);earliest[i] = 1;                    //初始化为1}}int totalTime = 0;                          //总耗时while (!node.empty()) {int u = node.front();topology.push_back(u);node.pop();for (int i = 0; i < graph[u].size(); ++i) {int v = graph[u][i].to;int l = graph[u][i].length;earliest[v] = max(earliest[v], earliest[u] + l);inDegree[v]--;if (inDegree[v] == 0) {node.push(v);totalTime = max(totalTime, earliest[v]);}}}for (int i = topology.size() - 1; i >= 0; --i) {int u = topology[i];if (graph[u].size() == 0) {latest[u] = earliest[u];            //汇点的最晚完成时间初始化} else {latest[u] = INF;                    //非汇点的最晚完成时间初始化}for (int j = 0; j < graph[u].size(); ++j) {int v = graph[u][j].to;int l = graph[u][j].length;latest[u] = min(latest[u], latest[v] - l);}}return totalTime;
}int main() {int n, m;while (scanf("%d%d", &n, &m) != EOF) {memset(graph, 0, sizeof(graph));memset(earliest, 0, sizeof(earliest));memset(latest, 0, sizeof(latest));memset(inDegree, 0, sizeof(inDegree));while (m--) {int from, to, length;scanf("%d%d%d", &from, &to, &length);graph[from].push_back(Edge(to, length));inDegree[to]++;}int answer = CriticalPath(n);printf("%d\n", answer);}return 0;
}


http://www.ppmy.cn/ops/151539.html

相关文章

【ROS2 中间件RMW】基于FastDDS共享内存实现ROS2跨进程零拷贝通讯

前言 谈及ROS2的通讯机制&#xff0c;话题通讯作为一个最为常用的通讯手段&#xff0c;相信大家都不为陌生。但是即便话题通讯提供了一种跨进程的通讯方式&#xff0c;我们难免无法防止其在发布和订阅 的时候传递的消息被进行内存中的一次拷贝。因此诞生了零拷贝(zero_copy)这…

内网渗透测试工具及渗透测试安全审计方法总结

1. 内网安全检查/渗透介绍 1.1 攻击思路 有2种思路&#xff1a; 攻击外网服务器&#xff0c;获取外网服务器的权限&#xff0c;接着利用入侵成功的外网服务器作为跳板&#xff0c;攻击内网其他服务器&#xff0c;最后获得敏感数据&#xff0c;并将数据传递到攻击者&#xff0…

基于微信小程序的校园运动场地预约系统设计与实现

一.前言 选题背景&#xff1a; 随着社会的进步和人们生活水平的提高&#xff0c;健康意识逐渐增强&#xff0c;越来越多的人开始关注和参与体育运动。在校园中&#xff0c;学生们也积极参与各种体育活动&#xff0c;以提升身体素质和促进全面发展。然而&#xff0c;由于校园运动…

[Qualcomm]Qualcomm MDM9607 SDK代码下载操作说明

登录Qualcomm CreatePoing Qualcomm CreatePointhttps://createpoint.qti.qua

记录一次微信小程序使用云能力开发的过程

对于开发微信小程序云开发不知从何起的同学们&#xff0c;可以当作一次参考。虽说官方有文档&#xff0c;有模板示例&#xff0c;但是这些都是片段或者完整的结果展示。对于初学或者开发经验较少的同学们&#xff0c;可能不知先从那里入手进行第一步的开发。下面解析下构建微信…

上位机工作感想-2024年工作总结和来年计划

随着工作年限的增增长&#xff0c;发现自己越来越不喜欢在博客里面写一些掺杂自己感想的东西了&#xff0c;或许是逐渐被工作逼得“成熟”了吧。2024年&#xff0c;学到了很多东西&#xff0c;做了很多项目&#xff0c;也帮别人解决了很多问题&#xff0c;唯独没有涨工资。来这…

hydra破解密码

hydra九头蛇是常用的密码破解工具 1、破解centos ssh密码 hydra -l root -P password.txt ssh://192.168.1.107:2222 hydra -l root -P password.txt -s 2222 192.168.1.107 ssh2、破解ftp hydra -l allen -P e:\aa.txt ftp://127.0.0.1 hydra -l allen -P e:\aa.txt ftp:…

KAGGLE竞赛实战2-捷信金融违约预测竞赛-part2-用lightgbm建立baseline

接着上一篇&#xff0c;用lightgbm建立baseline&#xff0c;发现模型效果得到了很大优化&#xff08;模型分提升为0.73) # In[211]: from sklearn.model_selection import cross_val_score,KFold # In[228]: import lightgbm as lgb # In[229]: from lightgbm import LGBMClas…