最短路
C - Heavy Transportation
这个题和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
这个是一道裸的最短路,但是因为是双向的,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 }