poj3268 最短路

题意:一些牛要从各自的农场到某一个指定农场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\n",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 }
dij

 

你可能感兴趣的:(poj)