继续复习
Dij变形,可用DP
题意:求点1到点n,最大的载重量。
转化为 ,1到n有多条路径,每条路径都有一个最小的边,求这些最小的边中的最大值
定义d[v] 表示到点v的最小边最大值 , 从u到v,边权为w,那么首先选出 temp = min( d[u] , w) , d[v] = max(d[v] , temp)
这是显然的,由u到v,边权为w,要经过这条边,必须流量不能比w大,否则流不过
溜过去之后,选最大的
用优先队列+dij变形来做,改变的只是松弛的条件
而这中问题,用dp来解也是显而易见的,不写了,以前写过
#include <cstdio> #include <cstring> #include <queue> #include <utility> using namespace std; #define N 1010 #define M 1000010 #define INF 0x3f3f3f3f #define max(a,b) ((a)>(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b)) int n,tot; int d[N]; int head[N]; struct edge { int u,v,w,next; }; typedef struct edge edge; typedef pair<int,int>pii; edge e[2*M]; void add(int u ,int v ,int w , int k) { e[k].u = u; e[k].v = v; e[k].w = w; e[k].next = head[u]; head[u] = k++; u = u^v; v = u^v; u = u^v; e[k].u = u; e[k].v = v; e[k].w = w; e[k].next = head[u]; head[u] = k++; } void bfs() { bool done[N]; priority_queue<pii , vector<pii> , less<pii> >q; while(!q.empty()) q.pop(); memset(d,-1,sizeof(d)); memset(done,false,sizeof(done)); d[1] = INF; q.push(make_pair(d[1],1)); while(!q.empty()) { int u,v,w; pii x = q.top(); q.pop(); u = x.second; if(done[u]) continue; done[u] = true; for(int k=head[u]; k!=-1; k=e[k].next) { int v = e[k].v; int w = e[k].w; int temp = min(d[u] , w); if(temp > d[v]) { d[v] = temp; q.push(make_pair(d[v] , v)); } } } } int main() { int T; scanf("%d",&T); for(int cas = 1; cas <= T; cas++) { scanf("%d%d",&n,&tot); tot *= 2; memset(head,-1,sizeof(head)); for(int i=0; i<tot; i+=2) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w,i); } bfs(); printf("Scenario #%d:\n",cas); printf("%d\n\n",d[n]); } }