zoukankan      html  css  js  c++  java
  • 沈阳网络赛D-Made In Heaven【k短路】【模板】

    One day in the jail, F·F invites Jolyne Kujo (JOJO in brief) to play tennis with her. However, Pucci the father somehow knows it and wants to stop her. There are NN spots in the jail and MM roads connecting some of the spots. JOJO finds that Pucci knows the route of the former (K-1)(K1)-th shortest path. If Pucci spots JOJO in one of these K-1K1 routes, Pucci will use his stand Whitesnake and put the disk into JOJO's body, which means JOJO won't be able to make it to the destination. So, JOJO needs to take the KK-th quickest path to get to the destination. What's more, JOJO only has TT units of time, so she needs to hurry.

    JOJO starts from spot SS, and the destination is numbered EE. It is possible that JOJO's path contains any spot more than one time. Please tell JOJO whether she can make arrive at the destination using no more than TT units of time.

    Input

    There are at most 5050 test cases.

    The first line contains two integers NN and M(1 leq N leq 1000, 0 leq M leq 10000)(1N1000,0M10000). Stations are numbered from 11 to NN.

    The second line contains four numbers S, E, KS,E,K and TT ( 1 leq S,E leq N1S,EN, S eq ESE, 1 leq K leq 100001K10000, 1 leq T leq 1000000001T100000000 ).

    Then MM lines follows, each line containing three numbers U, VU,V and W(1 leq U,V leq N, 1 leq W leq 1000)(1U,VN,1W1000) . It shows that there is a directed road from UU-th spot to VV-th spot with time WW.

    It is guaranteed that for any two spots there will be only one directed road from spot AA to spot B(1 leq A,B leq N, A eq B)(1A,BN,AB), but it is possible that both directed road <A,B><A,B> and directed road <B,A><B,A>exist.

    All the test cases are generated randomly.

    Output

    One line containing a sentence. If it is possible for JOJO to arrive at the destination in time, output "yareyaredawa" (without quote), else output "Whitesnake!" (without quote).

    样例输入

    2 2
    1 2 2 14
    1 2 5
    2 1 4

    样例输出

    yareyaredawa

    题目来源

    ACM-ICPC 2018 沈阳赛区网络预赛

    题意:

    给定有向图 找到从s到e的k短路 若k短路小于t 则输出yareyaredawa否则输出Whitesnake!

    思路:

    k短路模板题

    学习了一下k短路

    k短路 =  单源点最短路跑反向边 + 高级搜索A*

    A*算法结合了启发式方法和形式化方法;
    启发式方法通过充分利用图给出的信息来动态地做出决定而使搜索次数大大降低;
    形式化方法不利用图给出的信息,而仅通过数学的形式分析;

    算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向;
    当这条路径失败时,它会尝试其他路径;
    对于A*,估价函数=当前值+当前位置到终点的距离,即f(p)=g(p)+h(p),每次扩展估价函数值最小的一个;

    对于K短路算法来说,g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度;
    f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远;

    为了加速计算,h(p)需要在A*搜索之前进行预处理, 因为本题是有向图,所以将原图的所有边反向,再从终点t做一次单源点最短路径就能得到每个点的h(p)了;

    算法步骤:
    (1),将有向图的所有边反向,以原终点t为源点,求解t到所有点的最短距离;
    (2),新建一个优先队列,将源点s加入到队列中;
    (3),从优先级队列中弹出f(p)最小的点p,如果点p就是t,则计算t出队的次数;
    如果当前为t的第k次出队,则当前路径的长度就是s到t的第k短路的长度,算法结束;
    否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列;

    注意,k短路可能不存在

      1 // ConsoleApplication3.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
      2 //
      3 
      4 //#include "pch.h"
      5 #include <iostream>
      6 #include<algorithm>
      7 #include<stdio.h>
      8 #include<set>
      9 #include<cmath>
     10 #include<cstring>
     11 #include<map>
     12 #include<vector>
     13 #include<queue>
     14 #include<stack>
     15 
     16 #define inf 0x3f3f3f3f
     17 
     18 using namespace std;
     19 
     20 typedef long long LL;
     21 
     22 const int maxn = 1005;
     23 const int maxm = 100005;
     24 int n, m, s, ed, k, t;
     25 struct edge {
     26     int u, v;
     27     int cost;
     28     int nxt;
     29 }e[maxm], une[maxm];
     30 int head[maxn], unhead[maxn], cnt, uncnt;
     31 int dis[maxn];
     32 bool vis[maxn];
     33 struct node{
     34     int point;
     35     int g, f;
     36     friend bool operator < (node a, node b){
     37         return a.f == b.f?a.g>b.g:a.f>b.f;
     38     }
     39 };
     40 
     41 void init()
     42 {
     43     cnt = 0;
     44     uncnt = 0;
     45     memset(dis, inf, sizeof(dis));
     46     memset(vis, 0, sizeof(vis));
     47     memset(head, -1, sizeof(head));
     48     memset(unhead, -1, sizeof(unhead));
     49 }
     50 
     51 void addedge(int u, int v, int w)
     52 {
     53     e[cnt].u = u;
     54     e[cnt].v = v;
     55     e[cnt].cost = w;
     56     e[cnt].nxt = head[u];
     57     head[u] = cnt++;
     58     une[uncnt].u = v;
     59     une[uncnt].v = u;
     60     une[uncnt].cost = w;
     61     une[uncnt].nxt = unhead[v];
     62     unhead[v] = uncnt++;
     63 }
     64 
     65 void spfa(int e)
     66 {
     67     vis[e] = 1;
     68     dis[e] = 0;
     69     queue<int>que;
     70     que.push(e);
     71     while(!que.empty()){
     72         int u = que.front();
     73         que.pop();
     74         vis[u] = 0;
     75         for(int i = unhead[u]; i != -1; i = une[i].nxt){
     76             int tmp = dis[u] + une[i].cost;
     77             if(tmp < dis[une[i].v]){
     78                 dis[une[i].v] = tmp;
     79                 if(!vis[une[i].v]){
     80                     vis[une[i].v] = true;
     81                     que.push(une[i].v);
     82                 }
     83             }
     84         }
     85     }
     86 }
     87 
     88 int A_star(int s, int ed)
     89 {
     90     priority_queue<node>que;
     91     int shortest = 0;
     92     if(s == ed){
     93         k++;
     94     }
     95     if(dis[s] == inf){
     96         return -1;
     97     }
     98     node node0;
     99     node0.point = s;
    100     node0.g = 0;
    101     node0.f = dis[s] + node0.g;
    102     que.push(node0);
    103     while(!que.empty()){
    104         node0 = que.top();
    105         que.pop();
    106         if(node0.point == ed){
    107             shortest++;
    108             if(shortest == k){
    109                 return node0.g;
    110             }
    111         }
    112         
    113 
    114         for(int i = head[node0.point]; i != -1; i = e[i].nxt){
    115             node tmp;
    116             tmp.point = e[i].v;
    117             tmp.g = node0.g + e[i].cost;
    118             tmp.f = tmp.g + dis[tmp.point];
    119             que.push(tmp);
    120         }
    121     }
    122     return -1;
    123 }
    124 
    125 int main()
    126 {
    127     while(scanf("%d%d", &n, &m) != EOF){
    128         init();
    129         scanf("%d%d%d%d", &s, &ed, &k, &t);
    130         for(int i = 0; i < m; i++){
    131             int u, v, w;
    132             scanf("%d%d%d", &u, &v, &w);
    133             addedge(u, v, w);
    134         }
    135 
    136         spfa(ed);
    137         int kth = A_star(s, ed);
    138         if(kth <= t && kth != -1){
    139             printf("yareyaredawa
    ");
    140         }
    141         else{
    142             printf("Whitesnake!
    ");
    143         }
    144     }
    145 
    146     return 0;
    147 }
  • 相关阅读:
    Mac上使用Charles抓取https
    使用react-navigation 报错isMounted
    create-react-app创建出来项目,如何设置CSS模块化?
    Markdown 常用语法整理
    Git安装和使用
    页面重定向跳转
    AntDesign 踩坑大全
    js实现数组、对象深度克隆的两种办法
    wamp中mysql安装时能启动,重启后无法启动的解决办法
    前端开发工具收藏
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9676230.html
Copyright © 2011-2022 走看看