小美想游泳(贪心,dij)
题目来源:https://ac.nowcoder.com/acm/contest/88527/K
//
题意:存一个无向图(含权值),找到一条s到t的路线,该路线其中的最大权值最小。“比赛的时候题都读错了,以为是输出dij路线其中的最大权值”。
//
思路:也是贪心思想,只不过不是dij路径,比如一条路线是总权值99,但是每一步权值都是1。另一条路线总权值是66,两步,一步是32,一步是31,其中走的是总权值99的路线。
用一个dis[u]数组,表示从起点s到u点路径中的最大权值,跑dij的时候,判断 u-->y 中的dis[u]和w(u到y的权值),取两者较大值res,然后用dis[y]来比较,如果大于res,说明到y点有更小的权值取,那么就赋值给dis[y],然后放入队列中。
//
题解:
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e4+9;
vector<pair<int,int>>G[N];
vector<int>vis(N,0),dis(N,INT64_MAX),path(N,-1);
void dij(int st){
priority_queue<pair<int,int>>q;
q.push({0,st});
dis[st]=0;
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u]) { continue;}
vis[u]=1;
for(auto[x,y]:G[u]){//u->y
int res=max(dis[u],x);
if(dis[y]>res){
dis[y]=res;
q.push({-dis[y],y});
}
}
}
}
signed main()
{
int n,m,u,v,w,Max=-1;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
G[u].push_back({w,v});
G[v].push_back({w,u});
}
int s,t;
cin>>s>>t;
dij(s);
cout<<dis[t]<<endl;
return 0;
}
点击查看代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e4+9;
vector<pair<int,int>>G[N];
vector<int>vis(N,0),dis(N,INT64_MAX),path(N,-1);
void dij(int st){
priority_queue<pair<int,int>>q;
q.push({0,st});
dis[st]=0;
while(!q.empty()){
int u=q.top().second;
q.pop();
if(vis[u]) { continue;}
vis[u]=1;
for(auto[x,y]:G[u]){//u->y
if(dis[y]>dis[u]+x){
dis[y]=dis[u]+x;
path[y]=u;//y是由于u来的
q.push({-dis[y],y});
}
}
}
}
signed main()
{
int n,m,u,v,w,Min=INT64_MAX;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
G[u].push_back({w,v});
G[v].push_back({w,u});
}
int s,t;
cin>>s>>t;
dij(s);
int cnt=t;
while(path[cnt]!=-1){
// cout<<path[cnt]<<" ";
int tt=path[cnt];
//Max=max(Max,G[tt][tt].first);
for(auto x:G[cnt]){
if(x.second==tt){
Min=min(Min,x.first);
}
}
//Max=max(Max,G[cnt][tt].first);
cnt=path[cnt];
}
//cout<<endl;
cout<<Min<<endl;
return 0;
}
浙公网安备 33010602011771号