牛客练习赛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 分治求平面最近点对

牛客练习赛81 D.小 Q 与树(树剖+套路)

牛客练习赛84 D.牛客推荐系统开发之动态特征获取(set应用)

牛客练习赛85 D.数学家的迷题(bitset暴力)

牛客练习赛56 D.小翔和泰拉瑞亚 线段树