最短路

C - Heavy Transportation

 POJ - 1797 

这个题和B的类型差不多,都算是dijkstra的变形,但是这个更难想一点。让dis[i]存储1到各点最短路径的最大值。之所以可以用dijkstra,是因为对于每一次只要选当前最大的dis[v],那么这个dis一定是到v的最短路径的最大值。因为如果这条边不是的话,那么就有dis[v]=min(dis[u],g[u][v]),但是因为dis[v]是当前dis中的最大值,所以dis[v]>dis[u],如果g[u][v]>dis[v],那么dis[v]=dis[v],否则dis[v]=g[u][v]<dis[v],因此dis[v]一定是所求解,这样就可以通过松弛策略不断的推进。策略是和dijkstra求最短路一样的,表示的意义不太一样。

 1 #include <iostream>
 2 #include <cstring>
 3 #include <string>
 4 #include <map>
 5 #include <set>
 6 #include <algorithm>
 7 #include <fstream>
 8 #include <cstdio>
 9 #include <cmath>
10 #include <stack>
11 #include <queue>
12 using namespace std;
13 const double Pi=3.14159265358979323846;
14 typedef long long ll;
15 const int MAXN=1000+5;
16 const int dx[5]={0,0,0,1,-1};
17 const int dy[5]={1,-1,0,0,0};
18 const int INF = 0x3f3f3f3f;
19 const int NINF = 0xc0c0c0c0;
20 const ll mod=1e9+7;
21 int G[MAXN][MAXN];
22 int dis[MAXN],pre[MAXN];
23 void dijkstra(int n)
24 {
25     for(int i=1;i<=n;i++) 
26     {
27         if(G[1][i]!=0) dis[i]=G[1][i];
28     }
29     dis[1]=0;
30     int U[MAXN];
31     for(int i=1;i<=n;i++) U[i]=0;
32     U[1]=1;
33     for(int i=1;i<=n-1;i++)
34     {
35         int minn=0;int k;
36         for(int j=1;j<=n;j++)
37         {
38             if(U[j]) continue;
39             if(minn<dis[j])
40             {
41                 minn=dis[j];
42                 k=j;
43             }
44         }
45         U[k]=1;
46         for(int j=1;j<=n;j++)
47         {
48             if(!U[j]&&dis[j]<min(dis[k],G[k][j])&&G[k][j])
49                 dis[j]=min(dis[k],G[k][j]);
50         }
51     }
52     
53 }
54 int main()
55 {
56     int t;cin>>t;int cnt=1;
57     while(t--)
58     {
59         memset(G,0,sizeof(G));
60         memset(dis,0,sizeof(dis));
61         int n,m;cin>>n>>m;
62         while(m--)
63         {
64             int a,b,c;cin>>a>>b>>c;
65             G[a][b]=c;G[b][a]=c;
66         }
67         dijkstra(n);
68         printf("Scenario #%d:\n%d\n\n",cnt++,dis[n]);    
69     }
70     return 0;    
71 }

 

D - Silver Cow Party

 POJ - 3268

这个是一道裸的最短路,但是因为是双向的,1000*1000,floyed会卡,暴力dijkstra也会卡,T了大半天,看题解发现用了一个很巧妙的办法,只要把这个图的方向逆转,那么就是两次单源最短路,用两次dijkstra就可以解决。

  1 #include <iostream>
  2 #include <cstring>
  3 #include <string>
  4 #include <map>
  5 #include <set>
  6 #include <algorithm>
  7 #include <fstream>
  8 #include <cstdio>
  9 #include <cmath>
 10 #include <stack>
 11 #include <queue>
 12 using namespace std;
 13 const double Pi=3.14159265358979323846;
 14 typedef long long ll;
 15 const int MAXN=1000+5;
 16 const int dx[5]={0,0,0,1,-1};
 17 const int dy[5]={1,-1,0,0,0};
 18 const int INF = 0x3f3f3f3f;
 19 const int NINF = 0xc0c0c0c0;
 20 const ll mod=1e9+7;
 21 int G[MAXN][MAXN];
 22 int SG[MAXN][MAXN];
 23 int dis2[MAXN];
 24 int dis[MAXN];
 25 struct node{
 26     int to,cost;
 27     node(){}
 28     node (int x,int y)
 29     {
 30         this->to=x;
 31         this->cost=y;
 32         
 33     }
 34 
 35     bool operator<(const node&q) const{
 36         return cost >q.cost;
 37     }
 38 };
 39 void dij(int v,int n){
 40     int U[MAXN];memset(U,0,sizeof(U));
 41     memset(dis,INF,sizeof(dis));dis[v]=0;
 42     node tim;tim.cost=0;tim.to=v;
 43     priority_queue <node> P;P.push(tim);
 44     while(!P.empty())
 45     {
 46         tim=P.top();P.pop();
 47     //    cout <<tim.cost<<"  ";
 48         if(U[tim.to]) continue;
 49         U[tim.to]=1;
 50         for(int i=1;i<=n;i++)
 51         {
 52             if(!U[i]&&G[tim.to][i]&&dis[i]>dis[tim.to]+G[tim.to][i])
 53             {
 54                 dis[i]=dis[tim.to]+G[tim.to][i];
 55                 P.push(node(i,dis[i])); 
 56             }
 57         }
 58     }
 59 }
 60 void dij2(int v,int n){
 61     int U[MAXN];memset(U,0,sizeof(U));
 62     memset(dis2,INF,sizeof(dis2));dis2[v]=0;
 63     node tim;tim.cost=0;tim.to=v;
 64     priority_queue <node> P;P.push(tim);
 65     while(!P.empty())
 66     {
 67         tim=P.top();P.pop();
 68     //    cout <<tim.cost<<"  ";
 69         if(U[tim.to]) continue;
 70         U[tim.to]=1;
 71         for(int i=1;i<=n;i++)
 72         {
 73             if(!U[i]&&SG[tim.to][i]&&dis2[i]>dis2[tim.to]+SG[tim.to][i])
 74             {
 75                 dis2[i]=dis2[tim.to]+SG[tim.to][i];
 76                 P.push(node(i,dis2[i])); 
 77             }
 78         }
 79     }
 80 }
 81 int main()
 82 {
 83     int n,m,k;
 84     cin>>n>>m>>k;
 85     memset(dis,INF,sizeof(dis));
 86     while(m--)
 87     {
 88         int a,b,c;cin>>a>>b>>c;
 89         G[a][b]=c;
 90         SG[b][a]=c;
 91     }
 92     dij(k,n);
 93     dij2(k,n);
 94     int an=-1;
 95     for(int i=1;i<=n;i++)
 96     {
 97         if(an<dis[i]+dis2[i]) an=dis[i]+dis2[i];
 98     }
 99     cout <<an<<endl;
100     return 0;
101 }

 

posted @ 2019-05-05 14:13  Chuhanjing  阅读(220)  评论(0编辑  收藏  举报