题意:给定0-n+1个点,和m条边,让你找到一条从0到n+1的最短路,输出与0相连的结点。。。
析:很明显么,是Dijkstra算法,不过特殊的是要输出与0相连的边,所以我们倒着搜,也是从n+1找到0,
那么不就能找到与0相连的边么,注意判断相等值的时候。当时写错了好多次,就是没有考虑好边界。
代码如下:
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <cstring> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1000 + 100; int n; struct edge{ int from, to, dist; edge(int u, int v, int d) : from(u), to(v), dist(d) { } }; struct Headnode{ int d, u; Headnode(int dd, int uu) : d(dd), u(uu) { } bool operator < (const Headnode &rhs) const { return d > rhs.d; } }; struct Dijkstra{ int m; vector<edge> edges; vector<int> G[maxn]; bool done[maxn]; int d[maxn]; int p[maxn]; void init(){ for(int i = 0; i <= n+1; ++i) G[i].clear(); edges.clear(); } void addedge(int f, int t, int d){ edges.push_back(edge(f, t, d)); m = edges.size(); G[f].push_back(m-1); } void dijkstra(int s){ priority_queue<Headnode> q; for(int i = 0; i <= n+1; ++i) d[i] = INF; d[s] = 0; memset(done, 0, sizeof(done)); q.push(Headnode(0, s)); while(!q.empty()){ Headnode x = q.top(); q.pop(); int u = x.u; if(done[u]) continue; done[u] = true; for(int i = 0; i < G[u].size(); ++i){ edge &e = edges[G[u][i]]; if(d[e.to] >= d[u] + e.dist){ d[e.to] = d[u] + e.dist; p[e.to] = u; q.push(Headnode(d[e.to], e.to)); } else if(d[e.to] == d[u] + e.dist) p[e.to] = min(G[u][i], p[e.to]); } } } }; Dijkstra dijk; int main(){ int T, m; cin >> T; while(T--){ dijk.init(); scanf("%d %d", &n, &m); int u, v, c; for(int i = 0; i < m; ++i){ scanf("%d %d %d", &u, &v, &c); dijk.addedge(v, u, c); } dijk.dijkstra(n+1); if(dijk.d[0] >= INF) printf("-1\n"); else if(dijk.p[0] == n+1) printf("0\n"); else printf("%d\n", dijk.p[0]); } return 0; }
时间: 2024-10-23 19:07:23