题意:一些牛要从各自的农场到某一个指定农场X,然后再回各自的农场,给出一系列单向边,求总路程最短。这题看似麻烦,因为全部从X点返回各自农场是一个X到其他所有点的最短路径问题,但是从各自点到X点貌似就是N个点各自的最短路了。但其实可以这样,从所有点到X点就是逆的X点到其他点的过程,只不过走的路径也是反的,那么其实就很简单了,正向建边用于计算从X点返回各自点,而反向建边构成一张新的图,也是计算从X点返回各点的最短路径,其实这些边本来是从各点到X,但是反向建之后就变成了X到各点了,然后就变成简单的一点到多点的最短路,就可以跑两边最短路水过去了。
dij:
1 #include<stdio.h>
2 #include<string.h>
3 #include<queue>
4 using namespace std;
5 const int MAXM=100000;
6 int head1[1005],next1[MAXM+5],point1[MAXM+5],val1[MAXM+5],dist1[1005],size1;
7 bool vis1[1005];
8 int head2[1005],next2[MAXM+5],point2[MAXM+5],val2[MAXM+5],dist2[1005],size2;
9 bool vis2[1005];
10 int n;
11 void add1(int a,int b,int v){
12 int i;
13 for(i=head1[a];~i;i=next1[i]){
14 if(point1[i]==b){
15 if(val1[i]>v)val1[i]=v;
16 return;
17 }
18 }
19 point1[size1]=b;
20 val1[size1]=v;
21 next1[size1]=head1[a];
22 head1[a]=size1++;
23 }
24
25 void add2(int a,int b,int v){
26 int i;
27 for(i=head2[b];~i;i=next2[i]){
28 if(point2[i]==a){
29 if(val2[i]>v)val2[i]=v;
30 return;
31 }
32 }
33 point2[size2]=a;
34 val2[size2]=v;
35 next2[size2]=head2[b];
36 head2[b]=size2++;
37 }
38
39 void spfa(int s){
40 int i;
41 memset(dist1,-1,sizeof(dist1));
42 dist1[s]=0;
43 memset(vis1,0,sizeof(vis1));
44 queue<int>q1;
45 q1.push(s);
46 vis1[s]=1;
47 while(!q1.empty()){
48 int u=q1.front();
49 q1.pop();
50 vis1[u]=0;
51 for(i=head1[u];~i;i=next1[i]){
52 int j=point1[i];
53 if(dist1[j]==-1||dist1[j]>dist1[u]+val1[i]){
54 dist1[j]=dist1[u]+val1[i];
55 if(!vis1[j]){
56 q1.push(j);
57 vis1[j]=1;
58 }
59 }
60 }
61 }
62 memset(dist2,-1,sizeof(dist2));
63 dist2[s]=0;
64 memset(vis2,0,sizeof(vis2));
65 queue<int>q2;
66 q2.push(s);
67 vis2[s]=1;
68 while(!q2.empty()){
69 int u=q2.front();
70 q2.pop();
71 vis2[u]=0;
72 for(i=head2[u];~i;i=next2[i]){
73 int j=point2[i];
74 if(dist2[j]==-1||dist2[j]>dist2[u]+val2[i]){
75 dist2[j]=dist2[u]+val2[i];
76 if(!vis2[j]){
77 q2.push(j);
78 vis2[j]=1;
79 }
80 }
81 }
82 }
83 int ans=0;
84 for(i=1;i<=n;i++){
85 if(ans<dist1[i]+dist2[i])ans=dist1[i]+dist2[i];
86 }
87 printf("%d
",ans);
88 }
89
90 int main(){
91 int m,s;
92 while(scanf("%d%d%d",&n,&m,&s)!=EOF){
93 memset(head1,-1,sizeof(head1));
94 size1=0;
95 memset(head2,-1,sizeof(head2));
96 size2=0;
97 int i;
98 for(i=1;i<=m;i++){
99 int a,b,v;
100 scanf("%d%d%d",&a,&b,&v);
101 add1(a,b,v);
102 add2(a,b,v);
103 }
104 spfa(s);
105 }
106 return 0;
107 }