zoukankan      html  css  js  c++  java
  • 【模板】 $ ext{K}$ 短路

    Tags

    搜索、( ext{A*})很酷很炫的算法


    • 定义二元组( ext{DIS(X,Now)})表示到达( ext{X})点,路程是( ext{Now})
    • 反向( ext{SPFA/Dijkstra})作为每个点的估价函数;
    • 从队首取出( ext{DIS}),扩展状态;
    • 每当获得一个( ext{DIS}​)就加入到( ext{priority_queue}​)里面去;

    Code:

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #define re register
    #define GC getchar()
    #define Clean(X,K) memset(X,K,sizeof(X))
    int Qread () {
    	int X = 0 ;	char C = GC ;
    	while (C > '9' || C < '0') C = GC ;
    	while (C >='0' && C <='9') {
    		X = X * 10 + C - '0' ;
    		C = GC ;
    	}
    	return X ;
    }
    const int Maxn = 5005 , Maxm = 400005 , INF = 20021020 << 2;
    int N , M , Head[Maxn] , En = 0 , Vis[Maxn] ;
    double Ek , Mdis[Maxn];
    struct DIS {
    	int X ;
    	double Now ;
    };
    bool operator < (const DIS &A , const DIS &B) {
    	return A.Now + Mdis[A.X ] > B.Now + Mdis[B.X ] ;
    }
    std :: priority_queue <DIS> Q ;
    struct Edge {
    	int From_Point , Goto_Point , Next_Edge ;
    	double Lenth_of_Edge ;
    };
    Edge E[Maxm] ;
    void Adg (int X , int Y , double L) {
    	E[++En].From_Point =X ;
    	E[En].Goto_Point = Y ;
    	E[En].Next_Edge = Head[X] ;
    	E[En].Lenth_of_Edge = L ;
    	Head[X] = En ;
    }
    void SPFA () {
    	std :: queue <int> Q ;
    	for (re int i = 1 ; i <= N; ++ i) Mdis[i] = INF ;
    	Clean (Vis , 0) , Mdis[N] = 0 ;
    	Q.push(N) ;
    	while (!Q.empty()) {
    		int Now = Q.front() ;
    		Q.pop() ;
    		Vis[Now] = 0 ;
    		for (re int i = Head[Now] ; i; i = E[i].Next_Edge ) {
    			double Dis = Mdis[Now] + E[i].Lenth_of_Edge ;
    			if (Mdis[E[i].Goto_Point ] > Dis) {
    				Mdis[E[i].Goto_Point ] = Dis ;
    				if (!Vis[E[i].Goto_Point ]) {
    					Vis[E[i].Goto_Point ] = 1 ;
    					Q.push(E[i].Goto_Point ) ;
    				}
    			}
    		}
    	}
    }
    DIS Mp (int X , double Now) {
    	DIS Ans ;
    	Ans.X = X , Ans.Now = Now ;
    	return Ans ;
    }
    int main () {
    //	freopen ("P2483.in" , "r" , stdin) ;
    	N = Qread () , M = Qread () ;
    	scanf ("%lf" , &Ek) ;
    	Clean (Head , 0) , En = 0 ;
    	for (re int i = 1 ; i <= M; ++ i) {
    		double L ;
    		int X = Qread () , Y = Qread () ;
    		scanf ("%lf" , &L) ;
    		Adg (Y , X , L) ;
    	}
    	SPFA () ;
    	Clean(Head , 0 ) , En = 0 , M <<= 1 ;
    	for (re int i = 1 ; i <= M ; ++ i) Adg (E[i].Goto_Point , E[i].From_Point , E[i].Lenth_of_Edge ) ;
    	M >>= 1 ;
    	Q.push(Mp(1 , 0)) ;
    	int Ans = 0 ;
    	while (!Q.empty()) {
    		DIS Now = Q.top() ;
    		Q.pop() ;
    		if (Now.X == N) {
    			Ek -= Now.Now ;
    			if (Ek < 0) break ;
    			++ Ans ;
    			continue ;
    		}
    		for (re int i = Head[Now.X ] ; i; i = E[i].Next_Edge ) Q.push(Mp(E[i].Goto_Point , Now.Now + E[i].Lenth_of_Edge )) ;
    	}
    	printf ("%d
    " , Ans) ;
    	fclose (stdin) , fclose (stdout) ;
    	return 0 ;
    }
    

    Thanks!

  • 相关阅读:
    PTA——List Leaves
    pta——电话聊天狂人(c二叉树实现)
    Anti-SG游戏 与 SJ定理笔记(反Nim博弈)
    Unicode代码点与代码单元
    奇偶校验位
    IPv6与IPv4的位数
    0- win10配置java环境变量问题
    小计划
    路径问题
    getResource(path)的注意事项
  • 原文地址:https://www.cnblogs.com/bj2002/p/10545822.html
Copyright © 2011-2022 走看看