1. 程式人生 > >ACM-ICPC2018 沈陽賽區網絡預賽-D-Made In Heaven8

ACM-ICPC2018 沈陽賽區網絡預賽-D-Made In Heaven8

his direct aps and disk test case stat imp mos

A*算法:

A*,啟發式搜索,是一種較為有效的搜索方法。
我們在搜索的時候,很多時候在當前狀態,已經不是最優解了,但是我們卻繼續求解;這個就是暴力搜索浪費時間的原因。
我們在有些時候,往往可以根據一些信息推斷出繼續搜索是一種劣解。
所以如果能夠判斷出來的話,就可以不繼續了,以達到節省運行時間的目的。

估價函數:

為了提高搜索效率,我們可以對未來可能產生的代價進行預估。我們設計一個估價函數,以任意狀態輸入,計算出從該狀態到目標狀態所需代價的估計值。
在搜索時,我們總沿著當前代價+未來估價最小的狀態進行搜索。

估價函數需要滿足:
  設當前狀態state到目標函數所需代價的估計值為f(state)
  設在未來的搜索中,實際求出的從當前狀態state到目標狀態的最小代價為g(state)
  對於任意的state,應該有f(state)<=g(state)
也就是說,估價函數的估值不能大於未來實際代價,估價比實際代價更優。

第K短路:

根據估價函數的設計準則,在第K短路中從x到T的估計距離f(x)應該不大於第K短路中從x到T的實際距離g(x),於是,我們可以把估價函數f(x)定為從x到T的最短路徑長度,這樣不但能保證f(x)<=g(x),還能順應g(x)的實際變化趨勢。
實現過程:
1.預處理f(x),在反向圖上以T為起點求到每個點的最短路
2.定義堆,維護{p,g,h},p是某一個點,g是估價,h是實際,那麽g+h更小的點p會優先訪問
3.取出堆頂元素u擴展,如果節點v被取出的次數尚未達到k,就把新的{v,g,h+length(u,v)}插入堆中 4.重復第2-3步,直到第K次取出終點T,此時走過的路徑長度就是第K短路 因為估價函數的作用,圖中很多節點訪問次數遠小於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 MM (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 \neq ESE, 1 \leq K \leq 100001K10000, 1 \leq T \leq 1000000001T100000000 ).

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)(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 BB (1 \leq A,B \leq N, A \neq 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

技術分享圖片
#include <bits/stdc++.h>
using namespace std;
const int N=1005;
const int M=100005;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while (ch<0 || ch>9){if (ch==-) f=-1;ch=getchar();}
    while (ch>=0 && ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
int n,m,sta,en,kth,T,Ecnt,Eoppcnt;
int dist[N];
int times[N];
bool vis[N];
struct Edge{
    int to,next,val;}E[M],Eopp[M];//Eopp means Eopposite
int last[N],last_opp[N];
struct A_Star_node{
    int p,g,h;
    bool operator < (A_Star_node x)const
    {
        return x.g+x.h<g+h;
    }
};//means point  and a_Star:f(x)=g(x)+h(x);
priority_queue<A_Star_node>Q;
inline void add(int u,int v,int w)
{
    Ecnt++;
    E[Ecnt].next=last[u];
    E[Ecnt].to=v;
    E[Ecnt].val=w;
    last[u]=Ecnt;
}
inline void add_opposite(int u,int v,int w)
{
    Eoppcnt++;
    Eopp[Eoppcnt].next=last_opp[u];
    Eopp[Eoppcnt].to=v;
    Eopp[Eoppcnt].val=w;
    last_opp[u]=Eoppcnt;
}
void dij(int s,int e)
{
    memset(vis,0,sizeof(vis));
    memset(dist,127,sizeof(dist));
    int mi;
    dist[e]=0;
    for (int i=1;i<=n;i++)
    {
        mi=0;
        for (int j=1;j<=n;j++)
            if (!vis[j] && dist[mi]>dist[j])    mi=j;
        vis[mi]=1;
        for (int x=last_opp[mi];x;x=Eopp[x].next)
            dist[Eopp[x].to]=min(dist[Eopp[x].to],dist[mi]+Eopp[x].val);
    }
}
int A_Star(int s,int e)
{
    A_Star_node t1,tmp;
    memset(times,0,sizeof(times));
    while (!Q.empty()) Q.pop();
    t1.g=t1.h=0; t1.p=s;
    Q.push(t1);
    while (!Q.empty())
    {
        t1=Q.top();    Q.pop();
        times[t1.p]++;
        if (times[t1.p]<=kth && t1.h>T) return -1;//K短路之前的路已經比要求的時間長了,一定是不合法的方案
        if (times[t1.p]==kth && t1.p==e) return t1.h;
        if (times[t1.p]>kth) continue;
        for (int i=last[t1.p];i;i=E[i].next)
        {
            tmp.p=E[i].to;
            tmp.g=dist[E[i].to];
            tmp.h=E[i].val+t1.h;
            Q.push(tmp);
        }
    }
    return -1;
}
int main()
{
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        sta=read(); en=read(); kth=read(); T=read();
        int x,y,z;
        memset(last,0,sizeof(last));
        memset(last_opp,0,sizeof(last_opp));
        Ecnt=0;
        Eoppcnt=0;
        while (m--)
        {
            x=read(); y=read(); z=read();
            add(x,y,z);
            add_opposite(y,x,z);
        }
        dij(sta,en);
        if (sta==en) kth++;
        int ans=A_Star(sta,en);
        if (ans==-1||ans>T) puts("Whitesnake!");
        else puts("yareyaredawa");
    }
    return 0;
}
View Code

ACM-ICPC2018 沈陽賽區網絡預賽-D-Made In Heaven8