洛谷 [P2483] [模板] k短路

人生中的第一道黑题。。。
其实就是k短路模板

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
#include <queue>
using namespace std;
const int MAXN=400005;
int init(){
    int rv=0,fh=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') fh=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
            rv=(rv<<1)+(rv<<3)+c-'0';
            c=getchar();
        }
        return rv*fh;
    }
    int m,n,head1[MAXN],nume,head[MAXN];
    double tot,dis[MAXN];
    struct edge{
        int to,nxt;
        double dis;
    }e[MAXN],e1[MAXN];
    void adde1(int from,int to,double dis){
        e1[++nume].to=to;
        e1[nume].dis=dis;
        e1[nume].nxt=head1[from];
        head1[from]=nume;
    }
    void adde(int from,int to,double dis){
        e[++nume].to=to;
        e[nume].dis=dis;
        e[nume].nxt=head[from];
        head[from]=nume;
    }
    struct cmp{
        bool operator ()(const int &a,const int &b) const{
            return dis[a]>dis[b];
        }
    };
    void dij(){
        priority_queue <int,vector<int> ,cmp> q;
        q.push(n);
        memset(dis,0x7f,sizeof(dis));
        dis[n]=0;
        while(!q.empty()){
            int u=q.top();q.pop();
            for(int i=head1[u];i;i=e1[i].nxt){
                int v=e1[i].to;
                if(dis[v]>dis[u]+e1[i].dis){
                    dis[v]=dis[u]+e1[i].dis;
                    q.push(v);
                }
            }
        }
    }
    struct node{
        int v;
        double f,g;
        bool operator < (const node &a)const{
            if(this->f==a.f) return (this->g)>a.g;
            return (this->f)>a.f;
    }
};
void A_star(){
    node s;
    int cnt=0;
    s.v=1;s.f=dis[1];s.g=0.0;
    priority_queue <node>q;
    q.push(s);
    while(!q.empty()){
        node u=q.top();q.pop();//cout<<u.v<<" "<<u.f<<" "<<u.g<<endl;
        if(u.v==n){
            //cout<<tot<<endl;
            if(tot>=u.g) tot-=u.g,cnt++;
            else{
                cout<<cnt<<endl;
                return;
            }
        }
        for(int i=head[u.v];i;i=e[i].nxt){
            node v;
            v.v=e[i].to;
            v.g=u.g+e[i].dis;
            v.f=v.g+dis[e[i].to];
            //if(v.v==n) cout<<v.f<<endl;
            q.push(v);
        }
    }
    cout<<1<<endl;
}
int main(){
    n=init();m=init();scanf("%lf",&tot);
    for(int i=1;i<=m;i++){
        int u=init(),v=init();
        double di;
        scanf("%lf",&di);
        adde1(v,u,di);
    }
    dij();
//  cout<<dis[1]<<endl;
    nume=0;
    for(int i=1;i<=n;i++){
        for(int j=head1[i];j;j=e1[j].nxt){
            int v=e1[j].to;
            adde(v,i,e1[j].dis);
        }
    }
    //cout<<e[1].dis<<endl;
//  for(int i=head[1];i;i=e[i].nxt) cout<<e[i].to<<endl;
    A_star();
    return 0;
}

原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/8215027.html

时间: 2024-12-16 05:05:00

洛谷 [P2483] [模板] k短路的相关文章

洛谷 P3332 [ZJOI2013]K大数查询 || bzoj3110

用树套树就很麻烦,用整体二分就成了裸题.... 错误: 1.尝试线段树套平衡树,码农,而且n*log^3(n)慢慢卡反正我觉得卡不过去 2.线段树pushdown写错...加法tag对于区间和的更新应该要乘上区间长度的 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 typedef long long LL; 6 struct Q 7 { 8 LL

洛谷 P2483 [SDOI2010]魔法猪学院

P2483 [SDOI2010]魔法猪学院 k短路模板 1 #include<queue> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=10005; 7 int n,m,s,t,k,num,head1[maxn*100],head2[maxn*100],tot; 8 int nxt1[maxn*100]

【C++】最近公共祖先LCA(Tarjan离线算法)&amp;&amp; 洛谷P3379LCA模板

1.前言 首先我们介绍的算法是LCA问题中的离线算法-Tarjan算法,该算法采用DFS+并查集,再看此算法之前首先你得知道并查集(尽管我相信你如果知道这个的话肯定是知道并查集的),Tarjan算法的优点在于相对稳定,时间复杂度也比较居中,也很容易理解(个人认为). 2.思想 下面详细介绍一下Tarjan算法的思想: 1.任选一个点为根节点,从根节点开始. 2.遍历该点u所有子节点v,并标记这些子节点v已被访问过. 3.若是v还有子节点,返回2,否则下一步. 4.合并v到u上. 5.寻找与当前点

AC自动机(附洛谷P3769模板题)

首先,介绍一下AC自动机(Aho-Corasick automaton),是一种在一个文本串中寻找每一个已给出的模式串的高效算法. 在学习AC自动机之前,你需要先学习Trie树和KMP算法,因为AC自动机正式利用并结合了两者的思想. 说到实际的不同,其实AC自动机只是在Trie树上引入了一个类似KMP中next数组的东西叫做Fail指针. 对于每一个节点,Fail指针指向该节点所代表的字符串中,次长的.在Trie树中存在的后缀(因为最长的在Trie树种存在的后缀就是其本身)所代表的节点. 举例:

洛谷.3803.[模板]多项式乘法(FFT)

题目链接:洛谷.LOJ. FFT相关:快速傅里叶变换(FFT)详解.FFT总结.从多项式乘法到快速傅里叶变换. #include <cmath> #include <cctype> #include <cstdio> #include <algorithm> #define gc() getchar() const int N=1e6+5; const double PI=acos(-1); int n,m; struct Complex { double

洛谷.1919.[模板]A乘B Problem升级版(FFT)

题目链接:洛谷.BZOJ2179 //将乘数拆成 a0*10^n + a1*10^(n-1) + ... + a_n-1的形式 //可以发现多项式乘法就模拟了竖式乘法 所以用FFT即可 注意处理进位 //n位*n位最多就只有2n位了 //论putchar的速度..还是快的 #include <cmath> #include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar

洛谷P3375 [模板]KMP字符串匹配

To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了. 输入输出格式 输入格式: 第一行为一个字符串,即为s1(仅包含大写字母) 第二行为一个字符串,即为s2(仅包含大写字母) 输出格式: 若干行,每行包含一个整数,表示s2在s1中出现的位置 接下来1行,包括length(s2)个整

洛谷.3834.[模板]可持久化线段树(主席树 静态区间第k小)

题目链接 //离散化后范围1~cnt不要错 #include<cstdio> #include<cctype> #include<algorithm> //#define gc() getchar() #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++) const int N=2e5+5,MAXIN=2e6; int n,m,A[N],ref[N],cn

洛谷 P1993 小K的农场

P1993 小K的农场 题目描述 小K在MC里面建立很多很多的农场,总共n个,以至于他自己都忘记了每个农场中种植作物的具体数量了,他只记得一些含糊的信息(共m个),以下列三种形式描述: 农场a比农场b至少多种植了c个单位的作物, 农场a比农场b至多多种植了c个单位的作物, 农场a与农场b种植的作物数一样多. 但是,由于小K的记忆有些偏差,所以他想要知道存不存在一种情况,使得农场的种植作物数量与他记忆中的所有信息吻合. 输入输出格式 输入格式: 第一行包括两个整数 n 和 m,分别表示农场数目和小