k短路

k短路

好像是一个比较简单的东西

对于 正权有向图(displaystyle G=(V,E),V={V_i}_{i=1}^nE={(u_i,v_i,w_i)}_{i=1}^m)

(s)(t)的前(k)短路

考虑建立反图(G'=(V,E')),容易( ext{Dijkstra})求得(t)的单源最短路(dis_i),并且建立一棵最短路树

考虑(s ightarrow t)的最短路,一定是走了一些树边和非树边

选择一条非树边((u,v,w))会使长度增加(w'=w-(dis_u-dis_v)),称(w')为额外长度

考虑我们选择的非树边序列((u_i,v_i,w_i)),显然有:(u_{i+1})(v_i)在最短路树上的祖先

考虑用搜索扩展的方式来遍历所有路径情况

记录当前的节点(u),产生的额外长度(d),则每次的扩展可以归纳为

1.从(u)所有祖先中取出边的集合(S_u)

2.依次遍历(S_u)中的所有边((u_i,v_i,w'_i)),进入递归(u'=v_i,d'=d+w'_i)

每次扩展会产生一个新的状态,且恰好可以遍历每一个状态一次

[ ]

然而,为了求出前(k)短路,我们必须按照答案从小到大遍历

那么我们首先需要将集合(S_u)排序,从小到大遍历,其次要对于不同的递归情况按照大小扩展

容易想到用一个堆维护扩展的顺序,为了保存遍历(S_u)集合的过程,记录一个指针(p)

此时,用堆维护扩展的方法显然:

1.取出堆顶状态((u,d,p))

2.转移

2-1.在当前递归栈中移动(pleftarrow p+1),改变(d)

2-2.模拟上面,建立新的递归栈,同时令指针为(0)

得到(u'=v_{u,p},d'=d+w'_{v,0},p'=0)

如果暴力处理出(S_u),则预处理复杂度为(O(nmlog m)),状态扩展复杂度为(O(2klog k))

用可持久化可并堆处理(S_u)(p)记录当前堆顶节点指针

每次扩展(pleftarrow lson_p)或者(pleftarrow rson_p),增加一个扩展状态

则预处理复杂度以及空间复杂度为(O(mlog m)),状态扩展复杂度为(O(3klog k))

Luogu P2483

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cctype>
using namespace std;
typedef double db;
typedef pair <db,int> Pair;
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }

char IO;
template <class T=int> T rd(){
	T s=0; int f=0;
	while(!isdigit(IO=getchar())) f|=IO=='-';
	do s=(s<<1)+(s<<3)+(IO^'0');
	while(isdigit(IO=getchar()));
	return f?-s:s;
}

const int N=5010,M=2e5+10;
const db eps=1e-7,INF=1e18;

template <class T> class Heap{
public:
	T val;
	int h;
	Heap *ls,*rs;
	T top(){ return val; }
	Heap(){}
	Heap(Heap *x):val(x->val),h(x->h),ls(x->ls),rs(x->rs){ ; }
	Heap(T val):val(val),h(0),ls(0),rs(0){ ; }
	friend Heap* Union(Heap *x,Heap *y){
		if(!x) return y;
		if(!y) return x;
		if(y->val<x->val) swap(x,y);
		Heap* u=new Heap(x);
		u->rs=Union(u->rs,y);
		if(u->rs && (!u->ls || u->rs->h>u->ls->h)) swap(u->ls,u->rs);
		u->h=u->rs?u->rs->h+1:1;
		return u;
	}
	Heap* pop(){ return Union(ls,rs); }
	friend Heap* push(Heap *u,T val){ return Union(u,new Heap(val)); }
};
typedef Heap <Pair> Node;
Node *rt[N];

struct Edge{
	int to;db w;
	Edge *nxt;
	Edge(){}
	Edge(int to,db w,Edge* nxt):to(to),w(w),nxt(nxt){ ; }
};
Edge *head[N],*pre[N];
void AddEdge(int u,int v,db w){
	Edge* t=new Edge(v,w,head[u]);
	head[u]=t;
}
int n,m,fa[N];
db E,dis[N];

void Dijkstra(int u){
	static priority_queue <Pair,vector<Pair>,greater<Pair>> que;
	rep(i,1,n) dis[i]=INF;
	dis[u]=0,que.push({0,u});
	while(!que.empty()){
		int u=que.top().se;db d=que.top().fi; que.pop();
		if(dis[u]<d-eps) continue;
		for(Edge *i=head[u];i;i=i->nxt) {
			int v=i->to;
			if(dis[v]>dis[u]+i->w+eps) pre[v]=i,fa[v]=u,que.push({dis[v]=dis[u]+i->w,v});
		}
	}
}

void Construct(){
	static int I[N];
	rep(i,1,n) I[i]=i;
	sort(I+1,I+n+1,[&](int x,int y){ return dis[x]<dis[y]; });
	rep(u,1,n) {
		for(Edge *i=head[u];i;i=i->nxt) {
			int v=i->to;
			if(pre[v]==i) continue;
			rt[v]=push(rt[v],mp(i->w-(dis[v]-dis[u]),u));
		}
	}
	rt[n]=0;
	rep(j,1,n) {
		int u=I[j];
		rt[u]=Union(rt[u],rt[fa[u]]);
	}
}

struct State{
	db s;
	Node *rt;
	bool operator < (const State &__) const {
		return s>__.s;
	}
};

int ans;
void Kth_Path(){
	static priority_queue <State> que;
	if(dis[1]>E+eps) return void(puts("0"));
	ans=1,E-=dis[1];
	if(rt[1]) que.push({dis[1]+rt[1]->val.fi,rt[1]});
	while(!que.empty()) {
		State u=que.top(); que.pop();
		if(u.s>E+eps) break;
		int v=u.rt->val.se;
		ans++,E-=u.s;
		if(rt[v]) que.push({u.s+rt[v]->top().fi,rt[v]});
		u.s-=u.rt->val.fi;
		if(u.rt->ls) {
			Pair w=u.rt->ls->val;
			que.push({u.s+w.fi,u.rt->ls});
		}
		if(u.rt->rs) {
			Pair w=u.rt->rs->val;
			que.push({u.s+w.fi,u.rt->rs});
		}
	}
	printf("%d
",ans);
}

int main(){
	n=rd(),m=rd(),scanf("%lf",&E);
	rep(i,1,m){
		int u=rd(),v=rd();db w; scanf("%lf",&w);
		AddEdge(v,u,w);
	}
	Dijkstra(n);
	Construct();
	Kth_Path();
}
原文地址:https://www.cnblogs.com/chasedeath/p/14498606.html