当前位置:网站首页>拓扑排序 & 关键路径
拓扑排序 & 关键路径
2022-07-23 02:45:00 【JayGod、】
1、 拓扑排序
定义: 对一个有向无环图(Directed Acyclic Graph简称DAG) G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。
下面是阳阳的起床到9#504过程, 你能写出属于阳阳起床流程的拓扑序列嘛

正确顺序: 睁眼 -> 衬衣 -> 袜子 -> 外套 -> 鞋子 -> 出门 (不唯一)

拓扑序列: V1 -> V6 -> V3 -> V4 -> V2 -> V5 (不唯一)

#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int d[N], q[N], e[N], ne[N], h[N], idx;
int n, m;
void add (int a, int b) // 邻接表存边
{
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
bool topsort ()
{
int hh = 0, tt = -1;
for (int i = 1; i <= n; i ++)
if (!d[i]) q[++ tt] = i; // 先把入度为0 的存入队列
while (hh <= tt) // 数组模拟队列
{
int t = q[hh ++];
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (-- d[j] == 0) // 遍历此点所有联通的点, 如果去掉此点后入度为零, 即可继续存入
q[++ tt] = j;
}
}
return tt == n - 1; // 队列里可以保证所有均为拓扑排序, 若个数就是n个, 就说明可以构成拓扑排序
}
int main ()
{
cin >> n >> m;
memset (h, -1, sizeof h);
while (m --)
{
int a, b;
cin >> a >> b;
add (a, b);
d[b] ++; // 入度++
}
if (!topsort()) puts("-1");
else for (int i = 0; i < n; i ++) cout << q[i] << " "; // 队列里的元素恰好为拓扑排序序列
return 0;
}代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 3e4 + 10;
vector<int> q[N];//邻接表建图
int a, b;
int l, r;
map<pair<int, int>, int> mp;//输入时去除重边
struct node
{
int x;
int j;
};
int arr[N];
bitset<30001> dis[30001];//存路径之前有几个
queue<node> p;
void t()//拓扑排序函数
{
while (!p.empty())
{
node temp = p.front();//取队首
p.pop();
int len = q[temp.x].size();
for (int i = 0; i < len; i++)
{
arr[q[temp.x][i]]--;//入度减一
dis[q[temp.x][i]] |= dis[temp.x];//更新到该点的节点数
if (arr[q[temp.x][i]] == 0)//入度为0加入队列
{
int tem = dis[q[temp.x][i]].count();
p.push({q[temp.x][i], tem});//不能将dis[q[temp.x][i]].count()直接放进去,会报错,先赋给tem
}
}
}
return;
}
signed main()
{
cin >> a >> b;
for (int i = 1; i <= a; i++)
{
dis[i][i] = 1;
}
for (int i = 0; i < b; i++)
{
scanf("%d%d", &l, &r);
q[r].push_back(l);//反向入度,倒推
if (mp[{r, l}] != 1)//重复点不增加入度
{
arr[l]++;
}
mp[{r, l}] = 1;
}
for (int i = 1; i <= a; i++)
{
sort(q[i].begin(), q[i].end());//排序
q[i].erase(unique(q[i].begin(), q[i].end()), q[i].end());//排序后才能用这个方法去重边
}
for (int i = 1; i <= a; i++)
{
if (arr[i] == 0)//入度为零加入,多次加入,一次加入也行,把函数放外面
{
p.push({i, 1});
t();//函数,拓扑排序
}
}
for (int i = 1; i <= a; i++)
{
cout << dis[i].count() << endl;
}
return 0;
}
2、关键路径

最长路问题: 题目链接SDUTACM -problem-2498
#include <bits/stdc++.h>
using namespace std;
#define ios ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
const int N = 10010, M = 50010;
int h[N], e[M], w[M], ne[M], idx;
int dist[N];
bool st[N];
int r[N], C[N];
int path[N]; // 记录其father
int npath[N]; // 记录这条路径的条数, 处理字典序
int s, en; // 起点终点
vector<int> a;
void add(int a, int b, int c) {
e[idx] = b, ne[idx] = h[a]++, w[idx] = -1 * c, h[a] = idx++; // 最长路问题转化为权值取负的最短路问题 spfa
}
int spfa(int x) {
// ios;
memset(dist, 0x3f, sizeof dist);
dist[x] = 0;
queue<int> q;
q.push(x);
st[x] = 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] && (npath[j] == npath[t] + 1 && path[j] > j || j > t)) { // 取字典序较小的
path[j] = t;
npath[j] = npath[t] + 1;
dist[j] = dist[t] + w[i];
if (!st[j]) q.push(j), st[j] = true;
}
}
}
return dist[en];
}
int main() {
int n, m;
ios;
while (cin >> n >> m) {
idx = 0;
memset(st, 0, sizeof st);
memset(path, 0, sizeof path);
memset(C, 0, sizeof C);
memset (npath, 0, sizeof npath);
memset(r, 0, sizeof r);
a.clear();
memset(h, -1, sizeof h);
while (m--) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
r[b]++; // 入度
C[a] ++; // 出度
}
for (int i = 1; i <= n; i++)
if (!r[i])
s = i;
else if (!C[i])
en = i;
int res = -1 * spfa(s);
cout << res << endl;
while (path[en]) { // 弹出路径
a.push_back(en);
a.push_back(path[en]);
en = path[en];
}
int x = 1;
for (int i = a.size() - 1; i >= 0; i--) {
if (x % 2 != 0)
cout << a[i] << " "; // 输出格式
else
cout << a[i] << '\n';
x++;
}
}
return 0;
}边栏推荐
- Peptide nucleic acid (PNA) coupled with membrane penetrating peptides (CCPs) (KFF) 3K to form CCPs PNA | peptide nucleic acid
- PNA modified polypeptide BZ Val Gly Arg PNA | BOC Val Leu Gly Arg PNA
- 567. Arrangement of strings
- 系统安全测试要怎么做,详细来说说
- 检测Windows安全缺陷工具wesng的学习与使用
- [ssm] exception handling
- 结合实战,浅析GB/T 28181(二)——设备目录同步
- 目前都有哪些年利率6%左右的保本理财产品?
- A convnet for the 2020s paper reading
- LeetCode 提供的main函数中 JsonArray 所使用的jar包
猜你喜欢

seatunnel 架构

How to preserve peptide nucleic acid | peptide nucleic acid containing azobenzene unit (n-pna) | 99Tcm labeled c-myc mRNA

2022-07-22:以下go语言代码输出什么?A:1;B:1.5;C:编译错误;D:1.49。 package main import “fmt“ func main() { var i

PNA peptide nucleic acid modified peptide suc ala PNA | 2-ala ala leupna | AC Phe Gly PNA

Is the sub database and sub table really suitable for your system? Talk about how to select sub databases, sub tables and newsql
![[BDSec CTF 2022] 部分WP](/img/00/25c1953a324fbf04e3baf592079978.png)
[BDSec CTF 2022] 部分WP

567. 字符串的排列

60道测开面试题,背完直接涨工资

实现多层级条件查询(类似京东多层级添加查询)

insert引起的db file sequential read之改善
随机推荐
Peptide nucleic acid (PNA) coupled with membrane penetrating peptides (CCPs) (KFF) 3K to form CCPs PNA | peptide nucleic acid
ES6 related interview question 3
软件质量管理实践全面总结
完成端口的几个重要问题
PNA modified polypeptide BZ Val Gly Arg PNA | BOC Val Leu Gly Arg PNA
Pytorch save and load model
kali下安装go环境
平台型企业如何解决分账核算业务呢?
实现方法pathListToMap,能够将输入的pathList转化为具有层级结构的map类型
PHP 脚本对 txt 内容进行分页案例
关于RapidSSL证书
js div 滚动到底部
spark分区算子partitionBy、coalesce、repartition
Redis 6.0源码学习 Simple Dynamic String
Use recursive string inversion and Full Permutation
MySQL数据库提权学习
PNA modified polypeptide suc ala Pro ala PNA | suc ala Glu Pro Phe PNA
Hide the PHP version information in the response header of the website server
Take a look at the multi line editing of vscode
Peptide nucleic acid coupled polypeptide ile Glu Gly Arg PNA (s-2222) | BOC Leu Gly Arg PNA