题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1631
解:先跑一遍最短路,把所有边都反过来以后,再跑一遍
程序:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<vector> #define INF 2100000000 using namespace std; int n,root,m,dis[2000],ans[2000]; bool vis[2000]; vector<pair<int,int> >edge1[2000],edge2[2000]; void djk1() { for (int i=1;i<=n;i++) {dis[i]=INF;vis[i]=false;} dis[root]=0; for (;;) { int minx=INF,ch=-1; for (int i=1;i<=n;i++) if ((!vis[i])&&(dis[i]<minx)) { minx=dis[i]; ch=i; } if (ch==-1) return; vis[ch]=true; for (int i=0;i<edge1[ch].size();i++) { pair<int,int> y=edge1[ch][i]; if (dis[y.first]>dis[ch]+y.second) dis[y.first]=dis[ch]+y.second; } } } void djk2() { for (int i=1;i<=n;i++) {dis[i]=INF;vis[i]=false;} dis[root]=0; for (;;) { int minx=INF,ch=-1; for (int i=1;i<=n;i++) if ((!vis[i])&&(dis[i]<minx)) { minx=dis[i]; ch=i; } if (ch==-1) break; vis[ch]=true; for (int i=0;i<edge2[ch].size();i++) { pair<int,int> y=edge2[ch][i]; if (dis[y.first]>dis[ch]+y.second) dis[y.first]=dis[ch]+y.second; } } } int main() { scanf("%d%d%d",&n,&m,&root); int x,y,t; for (int i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&t); edge1[x].push_back(make_pair(y,t)); edge2[y].push_back(make_pair(x,t)); } djk1(); for (int i=1;i<=n;i++) ans[i]=dis[i]; djk2(); int now=0; for (int i=1;i<=n;i++) if (ans[i]+dis[i]>now) now=ans[i]+dis[i]; printf("%d\n",now); return 0; }