牛客练习赛105 D.点分治分点(spfa&bfs)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客练习赛105 D.点分治分点(spfa&bfs)相关的知识,希望对你有一定的参考价值。
牛客练习赛105 D.点分治分点(spfa&bfs)
最小路径最大化,这个状态是可以类似spfa or dijkstra转移的。
对于结点 u u u 连接的结点 v v v。
if(dis[v]<min(dis[u],w))
dis[v] = min(dis[u],w);
显然这样更新是对的,因为如果w<dis[u] 那么答案就是w,用w更新dis[v],否则所有到u 再到v的路径的 最短边的最大值就是 dis[u]。
时间复杂度: O ( m l o g n ) O(mlogn) O(mlogn)
spfa版
#include<bits/stdc++.h>
using namespace std;
#define add(x,y,z) G[x].push_back(y,z);
typedef pair<int,int> pa;
const int MAXN=1e5+5;
vector<pa>G[MAXN];
int dis[MAXN];
bool vis[MAXN];
void spfa(int s)
queue<int>q;
memset(dis,-1,sizeof(dis));
q.push(s),vis[s]=1,dis[s]=0x3f3f3f3f;
while(!q.empty())
int x=q.front();q.pop();
vis[x]=0;
for(auto [y,z]:G[x])
if(dis[y]<min(dis[x],z))
dis[y]=min(dis[x],z);
if(!vis[y]) q.push(y),vis[y]=0;
int main()
int n,m,s;
cin>>n>>m>>s;
int u,v,w;
for(int i=1;i<=m;++i)
scanf("%d %d %d",&u,&v,&w);
if(u!=v) add(u,v,w);
spfa(s);
for(int i=1;i<=n;++i) printf("%d ",dis[i]==0x3f3f3f3f?-1:dis[i]);
return 0;
dijkstra版
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int i,j,k,n,m,t,st,res[100500];
vector<pair<int,int>> v[100500];
int main()
ios::sync_with_stdio(0);
cin>>n>>m>>st;
memset(res,-1,sizeof(res));
for(i=1;i<=m;i++)
cin>>j>>k>>t;
if(k!=st)v[j].push_back(k,t);
priority_queue<pair<int,int> >q;
for(auto [i,j]:v[st])q.push(j,i);
while(!q.empty())
auto [w,id]=q.top();q.pop();
if(res[id]!=-1)continue;
res[id]=w;
for(auto [i,j]:v[id])
if(res[i]!=-1)continue;
q.push(min(w,j),i);
for(i=1;i<=n;i++)cout<<res[i]<<' ';
以上是关于牛客练习赛105 D.点分治分点(spfa&bfs)的主要内容,如果未能解决你的问题,请参考以下文章
牛客练习赛84:牛客推荐系统开发之标签重复度(点分治+动态开点权值线段树)
牛客练习赛11 B trie树+拓扑判环 E 分治求平面最近点对