大胆写Dijkstra !!
薄荷凉了夏
·
·
题解
看了楼下各位大佬的题解,发现大佬都是用的时间复杂度有点玄学SPFA,所以本蒟蒻就毫不犹豫的写了一个dijkstra+堆优化的程序。
然后看本题,其实个人认为和最短路意义上还是有区别的,因为题目是求可达终点的所有经过路径中最长的一段边权的最小值,所以它不一定要在s到t最短路上。所以裸的最短路板子肯定不行( 亲测0分 )
但是
我们仔细思考一下,对于任意一个点,到它的最大拥挤度的最小值肯定是
与它相邻的一个点的此值和他们之间的边权值取一个max,然后在所有max中取一个min!
这样我们就可以想到只要把板子里的松弛稍微修改一下,即只需把原本的求和改为取max就ok了!
另,注意此题应构无向图!!
代码
#include<bits/stdc++.h>
using namespace std;
inline int gi() {
int x=0,w=0;char ch=0;
while(!(ch>='0'&&ch<='9')) {
if(ch=='-') w=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return w?-x:x;
} //读入优化
const int maxn=3e5+1;
const int maxm=1e5+1;
priority_queue< pair<int,int> > q;//大根堆(后变小根堆)
int n,m,s,t,head[maxm],tot,dis[maxm],vis[maxm];
struct Edge {
int next,now,w;
}edge[maxn];
void make(int from,int to,int t) {
edge[++tot].next=head[from];
edge[tot].now=to;
edge[tot].w=t;
head[from]=tot;
} //链式前向星存图
void dijkstra() {
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
q.push(make_pair(0,s));
while(!q.empty()) {
int x=q.top().second; q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=edge[i].next) {
int k=max(dis[x],edge[i].w),r=edge[i].now;
//取max而不取和
if(k<dis[r]) {
dis[r]=k;
q.push(make_pair(-dis[r],r));
//取一个负就可以变为小根堆!!
}
}
}
}
int main()
{
n=gi(); m=gi(); s=gi(); t=gi();
for(int i=1,x,y,z;i<=m;i++) {
x=gi(); y=gi(); z=gi();
make(x,y,z);
make(y,x,z);
//构无向图
}
dijkstra();
printf("%d",dis[t]);
return 0;
}