本来想用Floyd算法,可惜超时,毕竟复杂度太高,而且并没有必要求出任意两点间的最短距离。
求两点间的最短路有两种方法,dijkstra和Bellman ,前者不能有负圈,后者可以有负圈,另外,Floyd也可以求带负圈的最短距离。
我们只需要求出x到其他个点的最短距离和个点到它的最短距离就行了。当然,我所写的还求了很多多余的量,是可以优化的。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> #include<vector> using namespace std; const int INF = 1000000; int n,m,x,a,b,c,d[1005][1005]; struct edge { int to,cost; edge(int to = 0,int cost = 0) : to(to),cost(cost) {} }; typedef pair<int,int> P; vector<edge> G[1005]; void dijkstra(int s) { priority_queue<P, vector<P> ,greater<P> > que; d[s][s] = 0; que.push(P(0,s)); while(!que.empty()) { P p = que.top(); que.pop(); int v = p.second; if(d[s][v]<p.first) continue; for(int i=0;i<G[v].size();i++) { edge e = G[v][i]; if(d[s][e.to]>d[s][v]+e.cost) { d[s][e.to] = d[s][v] + e.cost; que.push(P(d[s][e.to],e.to)); } } } } int main() { scanf("%d%d%d",&n,&m,&x); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j] = INF; for(int i=0;i<m;i++) { scanf("%d%d%d",&a,&b,&c); G[a].push_back(edge(b,c)); } dijkstra(x); for(int i=1;i<=n;i++) dijkstra(i); int sum = -1; for(int i=1;i<=n;i++) { int v = d[i][x]+d[x][i]; sum = max(sum,v); } printf("%d\n",sum); return 0; }
时间: 2024-12-06 22:17:47