拓扑排序不能有环
完全不连通,各点相互独立也可以
要是该最短路径的各点之间的路径总数量很大,则不成立
应该选A。顶点2被纳入确定顶点是在找到它的最短路径之后,那么5在它之前被纳入确定顶点的时候到4的距离就被更新成了11。
拓扑排序 (DFS和BFS及判断是否有环) - 糖豆爸爸 - 博客园 (cnblogs.com)
三种邻接表存图模板:vector邻接表、数组邻接表、链式前向星 - Dilthey - 博客园 (cnblogs.com)
Dijkstra算法优化~~你一定可以看懂的四种进阶优化_dijkstra算法优化方法-CSDN博客
C++中pair的用法_pair<int,int>-CSDN博客
堆优化版Dijkstra算法_迪克斯特拉算法性能-CSDN博客
一个工程被分解成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 }
Background
Special for beginners, ^_^
Description
战争时期,前线有 n 个哨所,每个哨所可能会与其他若干个哨所之间有通信联系。信使负责在哨所之间传递信息,当然,这是要花费一定时间的(以天为单位)。指挥部设在第一个哨所。当指挥部下达一个命令后,指挥部就派出若干个信使向与指挥部相连的哨所送信。当一个哨所接到信后,这个哨所内的信使们也以同样的方式向其他哨所送信。直至所有 n 个哨所全部接到命令后,送信才算成功。因为准备充足,每个哨所内都安排了足够的信使(如果一个哨所与其他k个哨所有通信联系的话,这个哨所内至少会配备k个信使)。
现在总指挥请你编一个程序,计算出完成整个送信过程最短需要多少时间。
Format
Input
输入第 1 行有两个整数 n 和 m,中间用 1 个空格隔开,分别表示有 n 个哨所和 m 条通信线路。1≤n≤100。
第 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 }