ACM-ICPC 2018 沈阳赛区网络预赛 D. Made In Heaven(约束第K短路)
题意:求11到nn的第kk短的路径长度,如果超过TT输出Whitesnake!Whitesnake!,否则输出yareyaredawayareyaredawa。
好无以为 , 这就是一道模板题, 当是与之不同的是有T的限制,还要注意是在所有满足条件的边中的第k条 , 比赛的时候题意理解问题,导致无法AC
#include<stdio.h> #include<string.h> #include<queue> #include<algorithm> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1024; const int maxm = 100008; int TIME; struct EDGE{ int v, nxt, w; }; struct NODE{ int pos, Cost, F; bool operator < (const NODE & rhs) const {//重载的时候注意符号 if(this->F == rhs.F) return this->Cost > rhs.Cost; return this->F > rhs.F; }; }; EDGE Edge[maxm]; EDGE REdge[maxm]; int Head[maxn], RHead[maxn]; int cnt, Rcnt; int N; void init() { memset(Head, -1, sizeof(Head)); memset(RHead, -1, sizeof(RHead)); cnt = Rcnt = 0; } void AddEdge(int from, int to, int weight) { Edge[cnt].w = weight; Edge[cnt].v = to; Edge[cnt].nxt = Head[from]; Head[from] = cnt++; } void AddREdge(int from, int to, int weight) { REdge[Rcnt].w = weight; REdge[Rcnt].v = to; REdge[Rcnt].nxt = RHead[from]; RHead[from] = Rcnt++; } int vis[maxn]; int H[maxn]; void SPFA(int st) { queue<int> que; memset(H, INF, sizeof(H)); memset(vis, 0, sizeof(vis)); H[st] = 0; que.push(st); while(!que.empty()){ int cur = que.front(); que.pop(); vis[cur] = 0; for(int i=RHead[cur]; i!=-1; i=REdge[i].nxt) { int v = REdge[i].v; if(H[v] > H[cur] + REdge[i].w) { H[v] = H[cur] + REdge[i].w; if(!vis[v]) { vis[v] = 1; que.push(v); } } } } } int A_Star(int s, int t, int k) { if(s == t) k++; if(H[s]==INF) return -1; priority_queue<NODE> que; NODE cur, into; cur.pos = s; cur.Cost = 0; cur.F = H[s]; que.push(cur); int CNT = 0; while(!que.empty()){ cur = que.top(); que.pop(); if(cur.Cost>TIME)///因为是最优最优的来,不条件的话,下面的也肯定吧满足, return -1; if(cur.pos == t) CNT++; if(CNT == k) return cur.Cost; for(int i=Head[cur.pos]; i!=-1; i=Edge[i].nxt){ into.Cost = cur.Cost+Edge[i].w; into.F = cur.Cost+Edge[i].w+H[Edge[i].v]; into.pos = Edge[i].v; que.push(into); } }return -1; } int main(void) { int M, K, S, des; while(~scanf("%d %d", &N, &M)){ init(); int from, to, weight; scanf("%d %d %d %d", &S, &des, &K,&TIME); while(M--){ scanf("%d %d %d",&from, &to, &weight); AddEdge(from, to, weight); AddREdge(to, from, weight);//建反向边 } SPFA(des);//求其他点到终点的最短路,作为H值 if(A_Star(S,des,K)!=-1) puts("yareyaredawa"); else puts("Whitesnake!"); } return 0; }