Dijkstra
不能判断负环


#include<iostream> #include<functional> #include<queue> #include<algorithm> #include<cstdio> using namespace std; typedef pair<int, int> P; struct Edge{ int to, w, next; }; const int maxn = 1010; const int maxm = 2000+10; const int inf = 0x7fffffff; //================================ Edge e[maxm * 2]; int dist[maxn]; int head[maxn]; int n, m, cnt; //=============================== void init(){ fill(head, head + n + 1, -1); cnt = 0; } void addedge(int u, int v, int w){ e[cnt].to = v; e[cnt].w = w; e[cnt].next = head[u]; head[u] = cnt++; } int dijkstra(int s,int t){ fill(dist, dist + n + 1, inf); dist[s] = 0; priority_queue<P, vector<P>, greater<P> > q; q.push(P(0, s)); while (!q.empty()){ P p = q.top(); q.pop(); int u = p.second; if (dist[u] < p.first) //剪枝 continue; for (int i = head[u];i!=-1; i = e[i].next){ int v = e[i].to; if (dist[v]>dist[u] + e[i].w){ dist[v] = dist[u] + e[i].w; q.push(P(dist[v],v)); } } } return dist[t]; } int main(){ ios::sync_with_stdio(false); cin >> n >> m; int a, b, c; init(); for (int i = 0; i < m; i++){ cin >> a >> b >> c; addedge(a, b, c); addedge(b, a, c); } cout << dijkstra(1,n) << endl; return 0; }
SPFA
可以判断负环


#include<iostream> #include<queue> #include<algorithm> #include<cstring> using namespace std; struct Edge{ int to, w, next; }; const int maxn = 2000 + 10; const int maxm = 3000 + 10; const int inf = 0x7fffffff; //=========================== Edge e[maxm * 2]; int head[maxn]; int dis[maxn]; bool inq[maxn]; int sum[maxn]; //记录每个点进队的次数 int n, m, cnt; //========================== void init(){ fill(head, head + n + 1, -1); cnt = 0; } void addedge(int u, int v, int w){ e[cnt].to = v; e[cnt].w = w; e[cnt].next = head[u]; head[u] = cnt++; } int spfa(int s, int t){ fill(dis, dis + n + 1, inf); memset(inq,false,sizeof inq); memset(sum,0,sizeof sum); dis[s] = 0; inq[s] = 1; sum[s]++; queue<int> q; q.push(s); while (!q.empty()){ int u = q.front(); q.pop(); inq[u] = 0; for (int i = head[u]; ~i; i = e[i].next){ int v = e[i].to; if (dis[v] > dis[u] + e[i].w){ dis[v] = dis[u] + e[i].w; sum[v] = sum[u] + 1; //更新次数 if (!inq[v]){ q.push(v), inq[v] = 1; } if (sum[v] >= n) return -inf; //若每个点进队的次数>=n,则判断有负环 } } } return dis[t]; } int main(){ ios::sync_with_stdio(false); int a, b, c; cin >> n >> m; init(); for (int i = 0; i < m; i++){ cin >> a >> b >> c; addedge(a, b, c); addedge(b, a, c); } int dis = spfa(1, n); if (dis == -inf) { cout << "存在负环" << endl; } else cout << dis << endl; return 0; }