zoukankan      html  css  js  c++  java
  • 【BZOJ1975】【SDOI2010】魔法猪学院(搜索,A*,贪心)

    我已经沉迷于粘贴题目地址了。。。

    题解

    很显然的贪心呀,
    就是一定是最短的若干条路径的长度
    所以,不断拓展k短路就可以了
    至于怎么用A*
    评估函数f(x)=dis[x]+g[x]
    其中,dis是到N号节点的距离
    g[x]是从起点出发的当前距离
    每次拿f(x)的最小的点进行BFS
    一直拓展到能量用完就行了
    很简单的啦。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAX 5100
    #define MAXL 201000
    #define INF 1e11
    #define lim 1e-11
    inline int read()
    {
        int x=0,t=1;char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line
    {
    	int v,next;double w;
    }e[MAXL*2];
    int h[MAX],cnt=1;
    inline void Add(int u,int v,double w)
    {
    	e[cnt]=(Line){v,h[u],w};
    	h[u]=cnt++;
    }
    int N,M;
    double En;
    double dis1[MAX];
    bool vis[MAX];
    int ans;
    void SPFA1()
    {
    	for(int i=1;i<=N;++i)dis1[i]=INF;
    	dis1[N]=0;vis[N]=true;
    	queue<int> Q;while(!Q.empty())Q.pop();
    	Q.push(N);
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for(int i=h[u];i;i=e[i].next)
    		{
    			if(i&1)continue;
    			int v=e[i].v;
    			if(dis1[v]>dis1[u]+e[i].w)
    			{
    				dis1[v]=dis1[u]+e[i].w;
    				if(!vis[v])
    				{
    					vis[v]=true;
    					Q.push(v);
    				}
    			}
    		}
    		vis[u]=false;
    	}
    }
    struct Node
    {
    	double val;
    	int num;
    };
    inline bool operator <(Node a,Node b)
    {
    	return a.val+dis1[a.num]>b.val+dis1[b.num];
    }
    void SPFA()
    {
    	priority_queue<Node> Q;while(!Q.empty())Q.pop();
    	Q.push((Node){0.00,1});
    	while(!Q.empty())
    	{
    		Node u=Q.top();Q.pop();
    		if(u.val-En>lim||lim>En)break;
    		if(u.num==N)ans++,En-=u.val;
    		for(int i=h[u.num];i;i=e[i].next)
    		{
    			if((i^1)&1)continue;
    			int v=e[i].v;
    			if(u.val+e[i].w-En>lim)continue;
    			Q.push((Node){u.val+e[i].w,v});
    		}
    	}
    }
    int main()
    {
    	N=read();M=read();
    	scanf("%lf",&En);
    	for(int i=1;i<=M;++i)
    	{
    		int u=read(),v=read();double w;
    		scanf("%lf",&w);
    		Add(u,v,w);Add(v,u,w);
    	}
    	SPFA1();
    	SPFA();
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    C++三大特性之多态
    内向者沟通圣经:4P法(Preparation,Presence,Push,Practice)
    RTP/RTCP、TCP、UDP、RTMP、RTSP
    网络七层协议
    预防U盘被病毒侵害的方法
    Win8安装程序出现2502、2503错误解决方法
    小L的区间求和
    【剑指offer-12】矩阵中的路径
    【剑指offer】数值的整数次方
    【剑指offer】二进制中1的个数
  • 原文地址:https://www.cnblogs.com/cjyyb/p/7623761.html
Copyright © 2011-2022 走看看