找到一个入度为0的点作为拓扑序列的第一个点;
把该点和该点所有的边从图中删去;
再在新的图中选择一个入度为0的点作为拓扑排序的第二个点;
以此类推,如果所有节点尚未删去时找不到入度为0的点则说明剩余节点存在环路,不存在拓扑排序。
3. 问题解决#include2.2 AcWing 849. Dijkstra求最短路 I 1. 问题描述 2. 问题分析#include #include using namespace std; const int N = 1e5 + 10; int n, m; int h[N], e[N], ne[N], idx; int d[N]; int q[N]; void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } bool top_sort() { int hh = 0, tt = -1; for(int i = 1; i <= n; i++) if(!d[i]) q[++ tt] = i; 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; } int main() { scanf("%d%d", &n, &m); memset(h, -1, sizeof(h)); for(int i = 0; i < m; i++) { int a, b; scanf("%d%d", &a, &b); add(a, b); d[b]++; } if(!top_sort()) puts("-1"); else { for(int i = 0; i < n; i++) printf("%d ", q[i]); putchar('n'); } return 0; }
进行n次迭代去确定每个点到起点的最小值,最后输出的终点即为我们要找到的最短路的距离
3. 问题解决#include2.3 蓝桥杯 12届:双向排序 1. 问题描述 2. 问题分析#include #include using namespace std; const int N = 510; int n, m; int g[N][N]; int dist[N]; bool st[N]; int dijkstra() { memset(dist, 0x3f, sizeof(dist)); dist[1] = 0; for(int i = 0; i < n-1; i++) { int t = -1; for(int j = 1; j <= n; j++) if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j; for(int j = 1; j <= n; j++) dist[j] = min(dist[j], dist[t] + g[t][j]); st[t] = true; } if(dist[n] == 0x3f3f3f3f) return -1; return dist[n]; } int main() { scanf("%d%d", &n, &m); memset(g, 0x3f, sizeof(g)); while(m--) { int a, b, c; scanf("%d%d%d", &a, &b, &c); g[a][b] = min(g[a][b], c); } printf("%dn", dijkstra()); return 0; }
这题的话,我用暴力的方法,只得了60分,暂时还未想到好的方法
3. 问题解决#include#include #include using namespace std; const int N = 1e5 + 10; int a[N]; int n, m; bool cmp(int a, int b) { return a > b; } int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) a[i] = i; while(m--) { int p, q; scanf("%d%d", &p, &q); if(!p) sort(a+1, a+q+1, cmp); else sort(a+q, a+n+1); } for(int i = 1; i <= n; i++) printf("%d ", a[i]); printf("n"); return 0; }



