【BZOJ1975】【SDOI2010】魔法猪学院(搜索,A*,贪心)

来源:互联网 发布:nginx并发连接数配置 编辑:程序博客网 时间:2024/05/20 04:26

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

题解

很显然的贪心呀,
就是一定是最短的若干条路径的长度
所以,不断拓展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-11inline 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\n",ans);    return 0;}
原创粉丝点击