常规操作:
- 先预处理出终点到起点(反图)的最短路(SPFA,Dijs)
- 再通过优先队列来对起点到终点的路径判断第 K K 短路
Code(模板):
int S,T,K;
struct edge{
int to,cost;
};
vector E[N],G[N];
int dis[N];
bool vis[N];
queue<int>Q;
void SPFA(){//反图 T->S
while(!Q.empty())Q.pop();
memset(vis,0,sizeof(vis));
memset(dis,0x3f3f3f3f,sizeof(dis));
Q.push(T);
vis[T]=1;
dis[T]=0;
while(!Q.empty()){
int x=Q.front();Q.pop();
vis[x]=0;
for(int i=0;i<(int)G[x].size();++i){
int y=G[x][i].to;
if(dis[y]>dis[x]+G[x][i].cost){
dis[y]=dis[x]+G[x][i].cost;
if(!vis[y]){
vis[y]=1;
Q.push(y);
}
}
}
}
}
struct Anode{
int to,d,all;
bool operator<(const Anode &_)const{
return all==_.all?d>_.d:all>_.all;
}
};
priority_queueStar;
int Astar(){//S->T
if(dis[S]==0x3f3f3f3f)return -1;
if(S==T)K++;
int cnt=0;
while(!Star.empty())Star.pop();
Star.push((Anode){S,0,dis[S]});
while(!Star.empty()){
Anode now=Star.top();Star.pop();
int x=now.to;
if(x==T){
cnt++;
if(cnt==K)return now.d;
}
for(int i=0;i<(int)E[x].size();i++){
int y=E[x][i].to;
Star.push((Anode){y,now.d+E[x][i].cost,now.d+E[x][i].cost+dis[y]});
}
}
return-1;
}
Description:
n个点,m条边的有向图,求s到t的第k短路。
Solution:
Code:
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define REP(i,f,t)for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define SREP(i,f,t)for(int i=(f),i##_end_=(t);i
#define DREP(i,f,t)for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define db double
#define LL long long
#define INF 0x3f3f3f3f
#define MINF 0xc0c0c0c0
#define inf 0x3f3f3f3f3f3f3f
#define Sz(a)sizeof(a)
#define mcl(a,b)memset(a,b,Sz(a))
#define mcp(a,b)memcpy(a,b,Sz(b))
#define pb push_back
#define fi first
#define se second
template<class T>inline bool chkmin(T&x,T y){return y1 :0;}
template<class T>inline bool chkmax(T&x,T y){return x1:0;}
inline LL Max(LL x,LL y){return x>y?x:y;}
inline LL Min(LL x,LL y){return xtypedef pair<int,int>PII;
#define N 1002
#define M 500002
int n,m;
int S,T,K;
int qwq1,qwq2,head1[N],head2[N];
struct edge{
int to,next,cost;
}E[M],G[M];
void addedge(int x,int y,int z){
E[qwq1]=(edge){y,head1[x],z};head1[x]=qwq1++;
G[qwq2]=(edge){x,head2[y],z};head2[y]=qwq2++;
}
int dis[N];
bool vis[N];
queue<int>Q;
struct Anode{
int to,d,all;
bool operator<(const Anode &_)const{
return all==_.all?d>_.d:all>_.all;
}
};
priority_queueStar;
void SPFA(){
while(!Q.empty())Q.pop();
mcl(dis,INF);
mcl(vis,0);
Q.push(T);
dis[T]=0;
vis[T]=1;
while(!Q.empty()){
int x=Q.front();Q.pop();
vis[x]=0;
for(int i=head2[x];~i;i=G[i].next){
int y=G[i].to;
if(chkmin(dis[y],dis[x]+G[i].cost)){
if(!vis[y]){
vis[y]=1;
Q.push(y);
}
}
}
}
}
int Astar(){
int cnt=0;
if(S==T)K++;
if(dis[S]==INF)return-1;
while(!Star.empty())Star.pop();
Star.push((Anode){S,0,dis[S]});
while(!Star.empty()){
Anode now=Star.top();Star.pop();
int x=now.to;
if(x==T){
cnt++;
if(cnt==K)return now.d;
}
for(int i=head1[x];~i;i=E[i].next){
int y=E[i].to;
Star.push((Anode){y,now.d+E[i].cost,now.d+E[i].cost+dis[y]});
}
}
return-1;
}
void Clear(){
qwq1=qwq2=0;
mcl(head1,-1);
mcl(head2,-1);
}
int main(){
// printf("sz=%d\n",(Sz(E)*2+Sz(dis)*2+Sz(Star)+Sz(Star))/1024/1024);
while(~scanf("%d%d",&n,&m)){
Clear();
REP(i,1,m){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
addedge(a,b,c);
}
scanf("%d%d%d",&S,&T,&K);
SPFA();
printf("%d\n",Astar());
}
return 0;
}