zoukankan      html  css  js  c++  java
  • BZOJ1975 SDOI2010魔法猪学院(启发式搜索+最短路+堆)

      对反图跑最短路求出每个点到终点的最短路径,令其为估价函数大力A*,第k次到达某个点即是找到了到达该点的非严格第k短路,因为估价函数总是不大于实际值。bzoj可能需要手写堆。正解是可持久化可并堆,至今是第二次见到这个那当然是不学啦。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    #define N 5010
    #define M 200010 
    char getc(){char c=getchar();while (c==10||c==13||c==32) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    int n,m,p[N],cnt[N],t,ans;
    bool flag[N];
    double tot,d[N];
    struct data{int to,nxt;double len;
    }edge[M];
    struct data2
    {
        int x;double d,r;
        bool operator <(const data2&a) const
        {
            return d+r<a.d+a.r||d+r==a.d+a.r&&d>a.d;
        }
    };
    struct heap
    {
        data2 a[M*12];int n;
        bool empty(){return n==0;}
        data2 top(){return a[1];}
        void push(data2 x)
        {
            a[++n]=x;int k=n;
            while (k>1&&a[k]<a[k>>1])
            swap(a[k],a[k>>1]),k>>=1;
        }
        void pop()
        {
            a[1]=a[n--];int k=1;
            while ((k<<1)<=n)
            {
                int x=k<<1;
                if (x<n&&a[x|1]<a[x]) x|=1;
                if (a[x]<a[k]) swap(a[x],a[k]),k=x;else break;
            }
        }
    }q;
    void addedge(int x,int y,double z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
    namespace reversegraph
    {
        int p[N]={0},t=0;
        struct data{int to,nxt;double len;}edge[M];
        void addedge(int x,int y,double z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;}
        void dijkstra()
        {
            for (int i=1;i<n;i++) d[i]=1e8;
            q.push((data2){n,0,0});
            for (;;)
            {
                while (!q.empty()&&flag[q.top().x]) q.pop();
                if (q.empty()) break;
                data2 x=q.top();q.pop();flag[x.x]=1;
                for (int i=p[x.x];i;i=edge[i].nxt)
                if (x.d+edge[i].len<d[edge[i].to])
                {
                    d[edge[i].to]=x.d+edge[i].len;
                    q.push((data2){edge[i].to,d[edge[i].to],0});
                }
            }
        }
    }
    void Astar(int lim)
    {
        q.push((data2){1,0,d[1]});
        while (!q.empty())
        {
            data2 x=q.top();q.pop();
            cnt[x.x]++;
            if (x.d+x.r>tot) break;
            if (x.x==n) {tot-=x.d,ans++;continue;}
            for (int i=p[x.x];i;i=edge[i].nxt)
            if (cnt[edge[i].to]<lim) q.push((data2){edge[i].to,x.d+edge[i].len,d[edge[i].to]});
        }
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("bzoj1975.in","r",stdin);
        freopen("bzoj1975.out","w",stdout);
        const char LL[]="%I64d
    ";
    #else
        const char LL[]="%lld
    ";
    #endif
        n=read(),m=read();cin>>tot;
        for (int i=1;i<=m;i++)
        {
            int x=read(),y=read();double z;scanf("%lf",&z);
            addedge(x,y,z);reversegraph::addedge(y,x,z);
        }
        reversegraph::dijkstra();
        Astar(tot/d[1]);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    Samba 4.0 RC3 发布
    SymmetricDS 3.1.7 发布,数据同步和复制
    Express.js 3.0 发布,Node.js 的高性能封装
    GIFLIB 5.0.1 发布,C语言的GIF处理库
    jQuery UI 1.9.1 发布
    SVN Access Manager 0.5.5.14 发布 SVN 管理工具
    DynamicReports 3.0.3 发布 Java 报表工具
    HttpComponents HttpClient 4.2.2 GA 发布
    AppCan 2.0 正式发布,推移动应用云服务
    Ruby 2.0 的新功能已经冻结
  • 原文地址:https://www.cnblogs.com/Gloid/p/9928404.html
Copyright © 2011-2022 走看看