【Codeforces 1473E】Minimum Path | Hierarchical shortest path

An observation formula, a question to draw a conclusion

Main idea:

You need to ask for it, from 1 to 11~ i i i2 ≤ i ≤ n {2 \ le i \ le n}2iThe weight of n is:路径总和-路径边权最大值+路径边权最小值the shortest path

Question idea:

Seen from 1 11 The shortest path to each point, then the shortest path problem must be considered.

But this problem is not easy to maintain, because it is impossible to maintain both the maximum value and the minimum value at the same time.

So change it and understand the formula required by the title as: on a path, the weight of an edge disappears, and the weight of an edge * 2 22 . Because the requirement is the smallest, then the largest edge weight must disappear, and the smallest edge weight *2 22 . So it just meets the requirements of the subject.

So you can build a layered map, but it is stuck in the direct layered map. Obviously, the answer to the layered map is wrong when there is only one edge, and it is impossible to remove the duplication.

So consider the state pressure at this time and add a two-dimensional state: one dimension represents whether the operation of the disappearing edge is performed, and the other dimension represents whether the operation is performed * 2 22 operations.

Then run a three-dimensional shortest path directly on this.

Put the code without heap optimization... (after being hacked)

Code:

/*** keep hungry and calm CoolGuang!  ***/
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e17+7;
const ll maxn = 1e6+700;
const ll mod= 1e9+7;
const ll up = 1e13;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){
    
    char c=getchar();T x=0,f=1;while(!isdigit(c)){
    
    if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){
    
    x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
ll num[maxn];
struct node{
    
    
	int e,next;
	ll w;
}edge[maxn];
int head[maxn];
int cnt = 0;
void addedge(int u,int v,int w){
    
    
	edge[cnt] = node{
    
    v,head[u],w};
	head[u] = cnt++;
}
struct N{
    
    
	int u,x,y;
};
ll dis[maxn][2][2];
int vis[maxn][2][2];
void bfs(){
    
    
	queue<N>q;
	
	dis[1][0][0] = 0;
	vis[1][0][0] = 1;
	q.push(N{
    
    1,0,0});
	while(!q.empty()){
    
    
		N u = q.front();q.pop();
		int id = u.u,x = u.x,y = u.y;
		vis[id][x][y] = 0;

		for(int i=head[id];~i;i=edge[i].next){
    
    
			int e = edge[i].e;
			ll w = edge[i].w;
			///debug(e)
			//debug(dis[e][x][y]);
			//debug(dis[e][x][1]);

			if(dis[e][x][y] > dis[id][x][y] + w){
    
    
				dis[e][x][y] = dis[id][x][y] + w;
				if(!vis[e][x][y]){
    
    
					q.push(N{
    
    e,x,y});
					vis[e][x][y] = 1;
				}
			}
			if(x == 0){
    
    
				if(dis[e][1][y] > dis[id][x][y]){
    
    
					dis[e][1][y] = dis[id][x][y];
					if(!vis[e][1][y]){
    
    
						q.push(N{
    
    e,1,y});
						vis[e][1][y] = 1;
					}
				}
			}
			if(y == 0){
    
    
				if(dis[e][x][1] > dis[id][x][y] + 2*w){
    
    
					dis[e][x][1] = dis[id][x][y] + 2*w;
					if(!vis[e][x][1]){
    
    
						vis[e][x][1] = 1;
						q.push(N{
    
    e,x,1});
					}
				}
			}
		}
	}
}
int main(){
    
    
	memset(head,-1,sizeof(head));

	read(n);read(m);
	for(int i=1;i<=n;i++)
		for(int k=0;k<2;k++)
			for(int j=0;j<2;j++)
				dis[i][k][j] = INF;
	for(int i=1;i<=m;i++){
    
    
		int x,y,w;
		read(x);read(y);read(w);
		if(x>y) swap(x,y); 
		if(x==1) dis[y][1][1] = w;
		addedge(x,y,w);
		addedge(y,x,w);
	}
	bfs();
	for(int i=2;i<=n;i++) printf("%lld ",dis[i][1][1]);
	printf("\n");
	return 0;
}
/***
***/

Guess you like

Origin blog.csdn.net/qq_43857314/article/details/112646144