C - Heavy Transportation
Hugo Heavy is happy. After the breakdown of the Cargolifter project(项目崩盘) he can now expand business(扩大业务)
But he needs a clever man who tells him whether there really is a way from the place his customer(顾客) has build his giant steel crane(巨型钢铁起重机) to the place where it is needed on which all streets can carry the weight.
题意:要从城市1到城市N运送货物,有M条道路,每条道路都有它的最大载重量,问从城市1到城市N运送最多的重量是多少。
其实题意很简单,就是找一条1-->N的路径,在不超过每条路径的最大载重量的情况下,使得运送的货物最多。一条路径上的最大
载重量为这个路径上权值最小的边;
思路:dijkstra 的变形,我们只需要每次选取离源点载货量最多的那条边,然后通过它去松弛所有路径上的最大载重量;
说一下为什么要每次选取离源点权值最大的那个点去松弛,我们知道原始的dijkstra是每次选取离源点最近的边去松弛使得求出的源
点到其余点的单源最短路径最短,那么我们这里希望让它路径上权值最小的边尽可能的大,我们就需要去选取离源点权值最大的点,使
得它的该路径的最大载重量大一些;
#include<iostream> #include<cstring> #include<stdio.h> #include<cmath> using namespace std; const int maxn=1005; int T,n,m; int mmp[maxn][maxn]; int dis[maxn]; bool vis[maxn]; void dij() { memset(vis,0,sizeof(vis)); for(int i=1; i<=n; i++) dis[i]=mmp[1][i]; for(int i=0; i<n; i++) { int temp=0; int k; for(int j=1; j<=n; j++) if(dis[j]>temp&&!vis[j]) temp=dis[k=j]; vis[k]=1; for(int j=1; j<=n; j++) if(dis[j]<min(dis[k],mmp[k][j])) dis[j]=min(dis[k],mmp[k][j]); } return ; } int main() { int u,v,w; scanf("%d",&T); for(int q=1; q<=T; q++) { memset(mmp,0,sizeof(mmp)); scanf("%d%d",&n,&m); for(int i=0;i<m;i++) { scanf("%d %d %d",&u,&v,&w); if(w>0) mmp[u][v]=mmp[v][u]=w; } dij(); printf("Scenario #%d:\n%d\n\n",q, dis[n]); } return 0; }