求第k短路
模板题 套模板即可
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <queue> using namespace std; const int maxn=1005; const int maxe=100005; struct State{ int f; // f=g+dis dis表示当前点到终点的最短路径,即之前的预处理 int g; //g表示到当前点的路径长度 int u; bool operator<(const State b)const{ if(f==b.f)return g>b.g; return f>b.f; } }; struct Edge{ int v; int w; int next; }edge[maxe],reedge[maxe]; int head[maxn],rehead[maxn]; int dis[maxn],vis[maxn]; int n,m; int cot; int s,t,k; void init(){ cot=0; //cot代表边的id 每条边的id都不相同 memset(head,-1,sizeof(head)); memset(rehead,-1,sizeof(rehead)); } void addedge(int u,int v,int w){ edge[cot].v=v; edge[cot].w=w; edge[cot].next=head[u];//记录上一次u的id是多少 这样方便遍历 初始值为-1 head[u]=cot;//head[u] 给这个u标记上独一无二的id reedge[cot].v=u; reedge[cot].w=w; reedge[cot].next=rehead[v]; rehead[v]=cot++; } void SPFA(){ queue<int>q; memset(vis,0,sizeof(vis)); memset(dis,-1,sizeof(dis)); int u,v; q.push(t); vis[t]=true;//vis表示当前点是否在队列 dis[t]=0; while(!q.empty()){ u=q.front(); q.pop(); vis[u] = 0; //rehead[u] 是u最后一次出现的id reedge[i].ne 代表第i次出现的边上一次出现的id for(int i=rehead[u];~i;i=reedge[i].next){ //~i取反 当i为-1时正好取反为0 退出for v=reedge[i].v; if(dis[v]>dis[u]+reedge[i].w || dis[v]==-1){ dis[v]=dis[u]+reedge[i].w; if(!vis[v]){ q.push(v); vis[v]=1; } } } } } int Astart(){ if(s==t)k++; if(dis[s]==-1)return -1; int cnt=0; priority_queue<State>q; // 优先队列 State a,b; a.g=0; a.u=s; a.f=a.g+dis[a.u]; q.push(a); while(!q.empty()){ b=q.top(); q.pop(); if(b.u==t){ cnt++; //printf("%d %d %d %d\n",b.f,b.g,b.u,dis[b.u]); if(cnt==k)return b.g; } for(int i=head[b.u];~i;i=edge[i].next){ a.g=b.g+edge[i].w; a.u=edge[i].v; a.f=a.g+dis[a.u]; q.push(a); } } return -1; } int main() { int u,v,w,T; while(scanf("%d%d",&n,&m)==2){ init(); scanf("%d%d%d%d",&s,&t,&k, &T); //起点 终点 第k条 时间T for(int i=0;i<m;i++){ scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } SPFA(); if (Astart() <= T && Astart() != -1) //小于等于T 并且有路才可以 printf("yareyaredawa\n"); else printf("Whitesnake!\n"); } return 0; }