网络赛(沈阳站)D题

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)(K−1)-th shortest path. If Pucci spots JOJO in one of these K-1K−1 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 MM (1 \leq N \leq 1000, 0 \leq M \leq 10000)(1≤N≤1000,0≤M≤10000). 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 N1≤S,E≤N, S \neq ES≠E, 1 \leq K \leq 100001≤K≤10000, 1 \leq T \leq 1000000001≤T≤100000000 ). Then MM lines follows, each line containing three numbers U, VU,V and WW (1 \leq U,V \leq N, 1 \leq W \leq 1000)(1≤U,V≤N,1≤W≤1000) . 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 BB (1 \leq A,B \leq N, A \neq B)(1≤A,B≤N,A≠B), but it is possible that both directed road

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <queue>
using namespace std;

struct Edge
{
    int to;
    int value;
    int next;
    bool operator < (const Edge &t) const
    {
        return t.value < value;
    }
};
struct Edge1
{
    int to;
    int value;
    int next;
};
struct Node
{
    int to;
    int f, g;
    bool operator < (const Node &t) const
    {
        if(t.f==f)
            return t.g < g;
        return t.f < f;
    }
};
Edge edge[100010];  //存储边与原图反向的图
Edge1 edge1[100010];    //存储原图
int adj[1010], adj1[1010], visited[1010], dis[1010], edgeNum, edgeNum1;
int N, M;

void Dijkstra(int start)
{
    int k;
    Edge t, cur;
    priority_queue<Edge> PQ;
    for(k=0; k<N; k++)
    {
        visited[k] = 0;
        dis[k] = INT_MAX;
    }
    t.to = start;   //起始顶点
    t.next = -1;
    t.value = 0;
    dis[start] = 0; //自己到自己路径为0
    PQ.push(t);
    visited[start] = 1; //标记以入队
    while(!PQ.empty())
    {
        cur = PQ.top();  //出队
        PQ.pop();
        visited[cur.to] = 0;    //标记出队
        for(int tmp = adj[cur.to]; tmp != -1; tmp = edge[tmp].next)
        {
            if(dis[edge[tmp].to] > dis[cur.to] + edge[tmp].value)
            {
                dis[edge[tmp].to] = dis[cur.to] + edge[tmp].value;
                if(visited[edge[tmp].to] == 0)
                {
                    PQ.push(edge[tmp]);
                    visited[edge[tmp].to] = 1;
                }
            }
        }
    }
}

int A_star(int start, int end, int k)
{
    Node e, ne;
    int cnt = 0;
    priority_queue<Node> PQ;
    if(start==end)
        k++;
    if(dis[start]==INT_MAX)     //无法到达终点
        return -1;
    e.to = start;
    e.g = 0;
    e.f = e.g + dis[e.to];
    PQ.push(e);
    while(!PQ.empty())
    {
        e = PQ.top();
        PQ.pop();
        if(e.to==end)
            cnt++;  //第cnt短路
        if(cnt==k)
            return e.g;
        for(int i=adj1[e.to]; i!=-1; i=edge1[i].next)
        {
            ne.to = edge1[i].to;
            ne.g = e.g + edge1[i].value;
            ne.f = ne.g + dis[ne.to];
            PQ.push(ne);
        }
    }
    return -1;
}

void addEdge(int a, int b, int len) //反向图添加边
{
    edge[edgeNum].to = b;
    edge[edgeNum].next = adj[a];
    edge[edgeNum].value = len;
    adj[a] = edgeNum++;
}

void addEdge1(int a, int b, int len)    //原图添加边
{
    edge1[edgeNum1].to = b;
    edge1[edgeNum1].next = adj1[a];
    edge1[edgeNum1].value = len;
    adj1[a] = edgeNum1++;
}

int main()
{
//    freopen("test.txt", "r", stdin);
    int a, b, len, i, s, t, k,maxt;
    while(scanf("%d %d", &N, &M)!=EOF)
    {
       scanf("%d %d %d %d", &s, &t, &k,&maxt);
        for(i=0; i<N; i++)
        {
            adj[i] = -1;
            adj1[i] = -1;
        }
        for(edgeNum1=edgeNum=i=0; i<M; i++)
        {
            scanf("%d %d %d", &a, &b, &len);
            addEdge1(a-1, b-1, len);    //构造原图
            addEdge(b-1, a-1, len); //构造反向图
        }
        if(N==1)
        {
            printf("yareyaredawa\n");
            return 0;
        }
        Dijkstra(t-1);  //求原图中各点到终点的最短路
        int ans = A_star(s-1, t-1, k);  //求第k短路
        if(ans==-1)printf("Whitesnake!\n");
        else if(ans>maxt)printf("Whitesnake!\n");
        else printf("yareyaredawa\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42825221/article/details/82558982