ACM-ICPC 2018 沈阳赛区网络预赛 Made In Heaven(K短路)题解

思路:K短路裸题

代码:

#include<queue>
#include<cstring>
#include<set>
#include<map>
#include<stack>
#include<string>
#include<cmath>
#include<vector>
#include<cstdio>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1000 + 10;
const int maxm = 10000 + 10;
const int seed = 131;
const ll MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
struct Edge{
    int v, w, next;
};
struct As{
    int f, g, pos;
    bool operator < (const As a) const{
        return a.f == f? a.g < g : a.f < f;
    }
};
int n, m, k, tot1, tot2, T;
int head1[maxn], head2[maxn], dis[maxn];
bool vis[maxn];
Edge edge1[maxm], edge2[maxm];
void init(){
    memset(head1, -1, sizeof(head1));
    memset(head2, -1, sizeof(head2));
    tot1 = tot2 = 0;
}
void addEdge(int u, int v, int w){
    edge1[tot1].v = v;
    edge1[tot1].w = w;
    edge1[tot1].next = head1[u];
    head1[u] = tot1++;

    edge2[tot2].v = u;
    edge2[tot2].w = w;
    edge2[tot2].next = head2[v];
    head2[v] = tot2++;
}
void spfa(int st){
    for(int i = 0; i <= n; i++) dis[i] = INF;
    memset(vis, false, sizeof(vis));
    vis[st] = true;
    dis[st] = 0;
    queue<int> q;
    while(!q.empty()) q.pop();
    q.push(st);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        vis[u] = false;
        for(int i = head2[u]; i != -1; i = edge2[i].next){
            int v = edge2[i].v;
            int w = edge2[i].w;
            if(dis[v] > dis[u] + w){
                dis[v] = dis[u] + w;
                if(!vis[v]){
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
}
int Astar(int st, int end){
   int cnt = 0;
   priority_queue<As> q;
   while(!q.empty()) q.pop();
   if(st == end) k++;
   if(dis[st] == INF) return -1;
   As a, b;
   a.pos = st, a.g = 0, a.f = a.g + dis[st];
   q.push(a);
   while(!q.empty()){
        a = q.top();
        q.pop();
        if(a.f > T) return -1;
        if(a.pos == end && a.f <= T){
            cnt++;
            if(cnt == k) return 1;
        }
        for(int i = head1[a.pos]; i != -1; i = edge1[i].next){
            b.pos = edge1[i].v;
            b.g = a.g + edge1[i].w;
            b.f = b.g + dis[b.pos];
            q.push(b);
        }
   }
   return -1;
}
int main(){
    int s, e;
    while(~scanf("%d%d", &n, &m)){
        init();
        scanf("%d%d%d%d", &s, &e, &k, &T);
        for(int i = 1; i <= m; i++){
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            addEdge(u, v, w);
        }
        spfa(e);
        int ans = Astar(s, e);
        if(ans == -1)
            printf("Whitesnake!\n");
        else
            printf("yareyaredawa\n");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/KirinSB/p/9631767.html

时间: 2024-11-06 23:16:54

ACM-ICPC 2018 沈阳赛区网络预赛 Made In Heaven(K短路)题解的相关文章

ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph

"Oh, There is a bipartite graph.""Make it Fantastic." X wants to check whether a bipartite graph is a fantastic graph. He has two fantastic numbers, and he wants to let all the degrees to between the two boundaries. You can pick up sev

ACM-ICPC 2018 沈阳赛区网络预赛 K. Supreme Number

A prime number (or a prime) is a natural number greater than 11 that cannot be formed by multiplying two smaller natural numbers. Now lets define a number NN as the supreme number if and only if each number made up of an non-empty subsequence of all

【ACM-ICPC 2018 沈阳赛区网络预赛 I】Lattice&#39;s basics in digital electronics

[链接] 我是链接,点我呀:) [题意] 每个单词的前缀都不同. 不能更明示了... 裸的字典树. 模拟一下.输出一下就ojbk了. [题解] #include <bits/stdc++.h> #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define all(x) x.begin(),x.end(

ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (贪心)

分析:贪心地删边后检查每个点的度即可,这也是正确的做法? #include <bits/stdc++.h> using namespace std; const int MAXN = 1e4+5; struct Edge{ int u,v,next; }edges[MAXN<<2]; int head[MAXN],tot; int deg[MAXN]; void init() { memset(head,-1,sizeof(head)); tot =0 ; memset(deg,0

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

A. Gudako and Ritsuka 留坑 B. Call of Accepted 留坑 C. Convex Hull 留坑 D. Made In Heaven 留坑 E. The cake is a lie 留坑 F. Fantastic Graph 留坑 G. Spare Tire 留坑 H. Hamming Weight 留坑 I. Lattice's basics in digital electronics 留坑 J. Ka Chang 留坑 K. Supreme Number

Made In Heaven 2018 沈阳赛区网络预赛 D题

求第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表示当前点到终点的最短路径,即之前的

ACM-ICPC 2018 沈阳赛区网络预赛 G. Spare Tire

这题很好啊,好在我没做出来...大概分析了一下,题目大概意思就是求 问所有满足1<=i<=n且i与m互素的ai之和 最开始我们队的做法是类似线性筛的方法去筛所有数,把数筛出来后剩下数即可,但是这样的是时间复杂度十分大,我们需要遍历每个质因 的倍数,这样最坏的复杂度是很大的1e8,因为我们需要把i的倍数筛到1e8,这样肯定不行,那么想想其他办法 我们想到了容斥-----(赛后想到的) 我们可以推处一个公式ai=i*i+i; 那么ai的前n项和Tn=n*(n+1)*(2*n+1)/6+n*(n+1

【ACM-ICPC 2018 沈阳赛区网络预赛 K】Supreme Number

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然每个数字只可能是1,3,5,7 然后如果3,5,7这些数字出现两次以上.显然两个3||5||7都能被11整除. 然后1的话最多能出现两次. 那么也就是说最多只可能有5位数字. 把小于等于5位的全都枚举一遍.求出合法的就好. 如果n>=5位就直接输出那个最大的就Ok. [代码] #include <bits/stdc++.h> #define LL long long #define rep1(i,a,b) for (

【 ACM-ICPC 2018 沈阳赛区网络预赛 D】Made In Heaven

[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 点可以重复走的k短路. [代码] #include <bits/stdc++.h> #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define all(x) x.begin(),x.end() #define pb push_bac