拓扑排序不能有环

完全不连通,各点相互独立也可以

要是该最短路径的各点之间的路径总数量很大,则不成立

应该选A。顶点2被纳入确定顶点是在找到它的最短路径之后,那么5在它之前被纳入确定顶点的时候到4的距离就被更新成了11。 

 

拓扑排序 (DFS和BFS及判断是否有环) - 糖豆爸爸 - 博客园 (cnblogs.com)

三种邻接表存图模板:vector邻接表、数组邻接表、链式前向星 - Dilthey - 博客园 (cnblogs.com)

Dijkstra算法优化~~你一定可以看懂的四种进阶优化_dijkstra算法优化方法-CSDN博客

C++中pair的用法_pair<int,int>-CSDN博客

堆优化版Dijkstra算法_迪克斯特拉算法性能-CSDN博客

7-1 任务拓扑排序

一个工程被分解成n个子任务,编号为0至n-1。要完成整个工程需要完成所有的子任务。其中一些子任务必须先于另外一些子任务被完成。给定各子任务之间的先后关系,请编写程序给出一个合理的任务完成顺序,若工程不可行,程序亦能识别。

输入格式:

输入第一行为两个整数n和e,均不超过100。n表示子任务数。接下来e行,表示已知的两个子任务间的先后关系,每行为两个整数a和b,表示任务a必须先于任务b完成。

输出格式:

若工程不可行(一些子任务以自己为先决条件),输出“unworkable project”;若工程可行,输出为1行整数,每个整数后一个空格,为n个子任务的编号,表示子任务的完成顺序,如果有多种可能的顺序,则输出字典序最小者。

注:字典序,即对象在字典中的顺序。对于两个数字序列,从第一个数字开始比较,当某一个位置的数字不同时,该位置数字较小的序列,字典序较小,例如1 2 3 9比1 2 4 5小,1 2 8 9比1 2 10 3小。

输入样例1:

3 2
0 1
1 2

输出样例1:

0 1 2 

输入样例2:

3 3
0 1
1 2
2 0

输出样例2:

unworkable project
 1 #include <iostream>
 2 #include<vector>
 3 #include<queue>
 4 using namespace std;
 5 #define vmaxnum 101
 6 vector<int> linjie[vmaxnum];//邻接表
 7 priority_queue<int, vector<int>, greater<int>>q;//小根堆
 8 vector<int>cnt;//判断是否有环
 9 int indu[vmaxnum] = {0};//全部赋值为0
10 int main()
11 {
12     int n, e;
13     int x, y;
14     cin >> n >> e;
15     for (int i = 0; i < e; i++) {
16         cin >> x >> y;
17         lingjie[x].push_back(y);//建立邻接表
18         indu[y]++;//保存入度
19     }
20     for (int i = 0; i < n; i++) {
21         if (indu[i] == 0) {
22             q.push(i);//如果入度为0,入队
23         }
24     }
25     while (!q.empty()) {//删边减入度
26         int j = q.top();//优先队列用top而不是front
27         q.pop();
28         cnt.push_back(j);//计数
29         for (int i = 0; i < lingjie[j].size(); i++) {
30             int z = lingjie[j][i];
31             indu[z]--;
32             if (indu[z] == 0) {
33                 q.push(z);
34             }
35         }
36     }
37     if (cnt.size()==n) {//判断是否有环
38         for (int i = 0; i < cnt.size(); i++) {
39             cout << cnt[i]<<" ";
40        }
41     }
42     else {
43         cout << "unworkable project";
44     }
45 
46     return 0;
47 }
View Code

 

 
7-2 信使

Background

Special for beginners, ^_^

Description

战争时期,前线有 n 个哨所,每个哨所可能会与其他若干个哨所之间有通信联系。信使负责在哨所之间传递信息,当然,这是要花费一定时间的(以天为单位)。指挥部设在第一个哨所。当指挥部下达一个命令后,指挥部就派出若干个信使向与指挥部相连的哨所送信。当一个哨所接到信后,这个哨所内的信使们也以同样的方式向其他哨所送信。直至所有 n 个哨所全部接到命令后,送信才算成功。因为准备充足,每个哨所内都安排了足够的信使(如果一个哨所与其他k个哨所有通信联系的话,这个哨所内至少会配备k个信使)。

现在总指挥请你编一个程序,计算出完成整个送信过程最短需要多少时间。

Format

Input

输入第 1 行有两个整数 n 和 m,中间用 1 个空格隔开,分别表示有 n 个哨所和 m 条通信线路。1n100。

第 2 至 m+1 行:每行三个整数 i,j,k,中间用 1 个空格隔开,表示第 i 个和第 j 个哨所之间存在通信线路,且这条线路要花费 k 天。

Output

输出仅一个整数,表示完成整个送信过程的最短时间。如果不是所有的哨所都能收到信,就输出 1。

Samples

样例输入1

4 4
1 2 4
2 3 7
2 4 1
3 4 6

样例输出1

11

Dijkstra算法优化~~你一定可以看懂的四种进阶优化_dijkstra算法优化方法-CSDN博客

堆优化版Dijkstra算法_迪克斯特拉算法性能-CSDN博客

 1 #include <iostream>
 2 #include<queue>
 3 #include<vector>
 4 #include<cstring>
 5 #define nmax 101
 6 using namespace std;
 7 typedef pair<int, int> p; //对于pair类型,优先队列会先比较第一个的值,若相等,再判断第二个的值。
 8 int minpath[nmax];//判断是否已经取得最短路径
 9 int dist[nmax];//源点到其他点的最短距离
10 typedef struct node {
11     int to;
12     int w;
13 }node;
14 void init() {
15     memset(dist, 0x3f, sizeof(dist));//初始距离为无穷大
16     memset(minpath, 0, sizeof(minpath));//最短路径未定
17 }
18 vector<node> linjie[nmax];
19 void dijkstra(int s) {//dijkstra优化算法
20     priority_queue<p, vector<p>, greater<p>> q;//小根堆
21     q.push(p(0, s));
22     while (!q.empty()) {
23         p temp = q.top();
24         q.pop();
25         int u = temp.second;
26         if (minpath[u])
27             continue;//如果已经找到最小路径就跳过后面的部分重新进入新一轮循环,可以看链接详细了解
28             minpath[u] = 1;
29             node n;
30             for (int i = 0; i < linjie[u].size(); i++) {
31                  n = linjie[u][i];
32                 if (minpath[n.to] == 0 && dist[n.to] > dist[u] + n.w) {//经过邻接结点的路径比之前更短
33                     dist[n.to] = dist[u] + n.w;
34                     q.push(p(dist[n.to], n.to));//入队
35                 }
36                 
37             }
38         
39 
40     }
41     return;
42 }
43 int main() {
44     int n, m;
45     cin >> n >> m;
46     init();
47     int i, j, k;
48     node temp1, temp2;
49     for (int x = 1; x <= m; x++) {
50         scanf_s("%d%d%d", &i, &j, &k);//防止超时,pta需要改成scanf
51         temp1.to = j;
52         temp2.to = i;
53         temp1.w = temp2.w = k;
54         linjie[i].push_back(temp1);
55         linjie[j].push_back(temp2);//无向图!!!坑点
56     }//建立邻接表
57     dist[1] = 0;
58     dijkstra(1);
59     int max = -1;
60     for (int i = 1; i <= n; i++) {
61         if (dist[i] == 0xf3)
62             break;
63         else if (dist[i] > max)
64             max = dist[i];
65     }//找最短时间
66         cout << max << endl;
67 }
View Code
posted on 2023-12-23 17:15  fmos  阅读(43)  评论(0编辑  收藏  举报