求助今晚abc E
  • 板块学术版
  • 楼主Pink_Cut_Tree
  • 当前回复15
  • 已保存回复16
  • 发布时间2024/1/6 21:41
  • 上次更新2024/1/7 08:54:31
查看原帖
求助今晚abc E
793625
Pink_Cut_Tree楼主2024/1/6 21:41

大致思路是如果两个节点的点权一样则将它们视为一个点,然后类似 Dijkstra 的方法跑

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5; 
int n,m,u,v;
int a[N];
vector<int>G[N];
struct path{
	int last_n; //上一个数
	int step; //步数
	int node; //当前节点
	int fa; //上一步从哪里来 
	friend bool operator<(path x,path y){
		return x.step<y.step;
	} 
};
bool vis[N];
priority_queue<path>Q;
int ans[N];
int fa[N];
int find(int x){
	return fa[x]==x?x:find(fa[x]);
}
int main(){
	cin.tie(0)->sync_with_stdio(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		fa[i]=i;
	}
	while(m--){
		cin>>u>>v;
		G[u].push_back(v);
		G[v].push_back(u);
		if(a[u]==a[v]){
			fa[u]=find(v);
		}
	}
	ans[1]=1;
	Q.push({a[1],1,1,-1});
	for(int i=1;i<=n;i++){
		fa[i]=find(i);
	}
	while(!Q.empty()){
		int u=Q.top().node; Q.pop();
		u=fa[u];
		if(vis[u]){
			continue;
		}
		if(u!=n){
			vis[u]=1;
		}
		for(int i=0;i<G[u].size();i++){
			int v=G[u][i];
			if(vis[v]||a[v]<a[u]){
				continue;
			}
			if(ans[v]<ans[u]+1){
				ans[v]=ans[u]+1;
				if(a[u]==a[v]){
					Q.push({a[v],ans[u],v,u});
				}
				else{
					Q.push({a[v],ans[u]+1,v,u});
				}
			}
		}
	} 
	cout<<ans[n];
return 0;
}

2024/1/6 21:41
加载中...