Acwing340. El camino más corto del diagrama jerárquico de la línea de comunicación

Enlace de tema

https://www.acwing.com/problem/content/description/342/

Título

Dado un gráfico no dirigido ponderado, ¿cuál es el peso más pequeño del k + 1º borde más grande en la ruta 1-n?

Ideas

Mantener el peso máximo / peso mínimo en la ruta es simple, simplemente cambie la definición de dis. Ahora el problema es cómo registrar el borde más grande k + 1. El borde más grande k + 1 en realidad puede equivaler a ignorar los bordes más grandes k en el proceso de ejecutar el camino más corto. Esto es más fácil de encontrar en la pregunta original. Después de la abstracción de la pregunta, debes cambiar tu mente.

La primera vez que toco el gráfico en capas, el gráfico en capas es para crear varios gráficos cuando hay diferentes operaciones en los puntos. En este problema, podemos crear k + 1 gráficas. Para la arista (u, v), además de conectar en cada gráfica, también atravesamos la u de la i-ésima gráfica y la v de la i + 1 ° gráfica ; La v del i-ésimo gráfico está conectada a la u del i + 1 ° gráfico, y el peso del borde es 0. Cuando la capa inferior "recorre" el borde con el peso de 0 hacia la capa superior, equivale a omitir el peso del borde de este borde. Luego, después de omitir k veces, pasará de la primera capa a la capa k + 1, en este caso La "distancia" al final de la capa k + 1 que desciende es lo que se requiere.

Código

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
//#define int long long
//#define double long double
using namespace std;
	typedef long long ll;
	const int maxn=1050*1050;
	const int maxe=20000+maxn; 
	const int inf=0x3f3f3f3f;
	int n,m;
	int head[maxn];
	struct Edge{
    
    
		int to;
		int next;
		int w;
	} edge[maxe];
	int cnt;
	
 	int dis[maxn];
	void init(){
    
    
		cnt=0;
		memset(head,-1,sizeof(head));
		return ;
	}
	inline void add(int u,int v,int w){
    
    
		edge[cnt].next=head[u];
		edge[cnt].to=v;
		edge[cnt].w=w;
		head[u]=cnt;
		cnt++;
	}
	typedef pair<int,int> P;
	void dij(int start){
    
    
		memset(dis,0x3f,sizeof(dis));
		priority_queue<P,vector<P>,greater<P> > q;
		dis[start]=0;
		q.push(P(0,start));
		while(!q.empty()){
    
    
			P p=q.top(); q.pop();
			int v=p.second;
			if(dis[v]<p.first)		continue;
			for(int i=head[v];~i;i=edge[i].next){
    
    
				int tmp=edge[i].to;
				if(dis[tmp]>max(dis[v],edge[i].w)){
    
    
					dis[tmp]=max(dis[v],edge[i].w);
					q.push(P(dis[tmp],tmp));
				}
			}
		}
		return ;
	}

	int main(){
    
    
		IOS
		init();
		int n,p,k;
		cin>>n>>p>>k;
		while(p--){
    
    
			int u,v,w;
			cin>>u>>v>>w;
			add(u,v,w);add(v,u,w);
			for(int i=0;i<k;i++){
    
    
				add(u+n*i,v+n*i+n,0);
				add(v+n*i,u+n*i+n,0);
				add(u+n*i+n,v+n*i+n,w);
				add(v+n*i+n,u+n*i+n,w);
			}
		}
		dij(1);
		if(dis[n+k*n]==inf)
			dis[n+k*n]=-1;
		cout<<dis[n+k*n]<<endl;
		return 0;
	}

	

Supongo que te gusta

Origin blog.csdn.net/TheSunspot/article/details/108896732
Recomendado
Clasificación