标签:sample tin real round ext least string air car
Input
Output
Sample Input
1 3 3 1 2 3 1 3 4 2 3 5
Sample Output
Scenario #1: 4
大意是求点1到n所有路径里最大的最短边权值。可以用堆优化的Dijkstra跑过。不同的是这里d数组的含义以及松弛操作都有所不同。这里d[i]代表从1到i所有路径最小边里最大的边的权值。松弛条件改为if(d[y]<min(d[x],z))d[y]=min(d[x],z).
要注意的是:
1.d数组要初始化为-INF,因为要求的是d[n]让其尽可能大。
2.d[1]要初始化为INF。因为如果按照dij模板初始化d[1]为0,第一次取出的是1号点,这时候d[y]为-INF,必然小于min(d[x],z),因为d[x]在第一次等于d[1]等于0,所以最终d数组将全部为0,得不到答案。
2.pair的第一维不用加负号,因为优先队列应该先让大的出来,所以不用按照蓝书上那样让其变为小根堆。
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <cstring> #include <queue> using namespace std; const int N=10005,M=200010;//两倍存双向边 int head[N],ver[M],edge[M],Next[M],d[N]; bool v[N]; int n,m,tot=0; priority_queue<pair<int,int> >q; void add(int x,int y,int z) { ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot; } void dijkstra() { memset(d,-0x3f,sizeof(d)); memset(v,0,sizeof(v)); d[1]=2000000000; q.push(make_pair(20000000,1)); while(q.size()) { int x=q.top().second; q.pop(); if(v[x])continue; v[x]=1; int i; for(i=head[x];i;i=Next[i]) { int y=ver[i]; int z=edge[i]; if(d[y]<min(d[x],z)) { d[y]=min(d[x],z); q.push(make_pair(d[y],y)); } } } } int main() { int t; cin>>t; int i,j,k; for(i=1;i<=t;i++) { tot=0; while(q.size())q.pop(); memset(head,0,sizeof(head)); memset(Next,0,sizeof(Next)); scanf("%d%d",&n,&m); for(j=1;j<=m;j++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } dijkstra(); printf("Scenario #%d:\n",i); cout<<d[n]<<endl; cout<<endl; } }
POJ1797 Heavy Transportation (堆优化的Dijkstra变形)
标签:sample tin real round ext least string air car
原文地址:https://www.cnblogs.com/lipoicyclic/p/12319665.html