原题
题目分析
了解题意后会发现跑两次最短路就能解决问题了,首先考虑奶牛们回家时的路径,其实只要从聚餐点跑一次最短路,记为dis2[],而考虑奶牛们出发时的最短路,只需要把所有边反置一下,再从聚餐点跑一遍最短路,记为dis[],最后只需要找出牛i使得dis[i]+dis2[i]的值最小即为答案.普通的最短路可以用dijkstra跑,复杂度更低.
代码
1 #include <iostream> 2 #include <algorithm> 3 #include <utility> 4 #include <cstdio> 5 #include <cmath> 6 #include <cstring> 7 #include <string> 8 #include <vector> 9 #include <stack> 10 #include <queue> 11 #include <map> 12 #include <set> 13 14 using namespace std; 15 typedef long long LL; 16 const int INF_INT=0x3f3f3f3f; 17 const LL INF_LL=0x3f3f3f3f3f3f3f3f; 18 19 typedef pair<int,int> P; 20 int edge[2000][2000]; 21 int dis[2000],redis[2000]; 22 23 int n,m,x; 24 25 void dijkstra1(int s) 26 { 27 for(int i=1;i<=n;i++) dis[i]=INF_INT; 28 priority_queue<P,vector<P>,greater<P> > que; 29 que.push(P(0,s)); 30 dis[s]=0; 31 while(que.size()) 32 { 33 P p=que.top();que.pop(); 34 int from=p.second; 35 if(p.first>dis[from]) continue; 36 for(int i=1;i<=n;i++) 37 { 38 if(edge[from][i]!=INF_INT) 39 { 40 if(dis[i]>dis[from]+edge[from][i]) 41 { 42 dis[i]=dis[from]+edge[from][i]; 43 que.push(P(dis[i],i)); 44 } 45 } 46 } 47 } 48 } 49 50 void dijkstra2(int s) 51 { 52 for(int i=1;i<=n;i++) redis[i]=INF_INT; 53 priority_queue<P,vector<P>,greater<P> > que; 54 que.push(P(0,s)); 55 redis[s]=0; 56 while(que.size()) 57 { 58 P p=que.top();que.pop(); 59 int from=p.second; 60 if(p.first>redis[from]) continue; 61 for(int i=1;i<=n;i++) 62 { 63 if(edge[from][i]!=INF_INT) 64 { 65 if(redis[i]>redis[from]+edge[from][i]) 66 { 67 redis[i]=redis[from]+edge[from][i]; 68 que.push(P(redis[i],i)); 69 } 70 } 71 } 72 } 73 } 74 75 int main() 76 { 77 // freopen("black.in","r",stdin); 78 // freopen("black.out","w",stdout); 79 cin>>n>>m>>x; 80 for(int i=1;i<=n;i++) 81 for(int j=1;j<=n;j++) edge[i][j]=INF_INT; 82 for(int i=0;i<m;i++) 83 { 84 int from,to,cost; 85 scanf("%d %d %d",&from,&to,&cost); 86 edge[from][to]=min(edge[from][to],cost); 87 } 88 /* for(int i=1;i<=n;i++) 89 for(int j=1;j<=n;j++) if(edge[i][j]!=INF_INT) printf("edge %d %d %d\n",i,j,edge[i][j]);*/ 90 dijkstra1(x); 91 // for(int i=1;i<=n;i++) printf("dis[%d]=%d\n",i,dis[i]); 92 for(int i=1;i<=n;i++) 93 for(int j=1;j<i;j++) swap(edge[i][j],edge[j][i]); 94 /* for(int i=1;i<=n;i++) 95 for(int j=1;j<=n;j++) if(edge[i][j]!=INF_INT) printf("edge %d %d %d\n",i,j,edge[i][j]);*/ 96 dijkstra2(x); 97 // for(int i=1;i<=n;i++) printf("redis[%d]=%d\n",i,redis[i]); 98 int ans=0; 99 for(int i=1;i<=n;i++) ans=max(ans,dis[i]+redis[i]); 100 cout<<ans<<endl; 101 return 0; 102 }