• 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;
    }
  • 相关阅读:
    PAT 1006 Sign In and Sign Out
    PAT 1004. Counting Leaves
    JavaEE开发环境安装
    NoSql数据库探讨
    maven的配置
    VMWARE 下使用 32位 Ubuntu Linux ,不能给它分配超过3.5G 内存?
    XCODE 4.3 WITH NO GCC?
    在苹果虚拟机上跑 ROR —— Ruby on Rails On Vmware OSX 10.7.3
    推荐一首让人疯狂的好歌《Pumped Up Kicks》。好吧,顺便测下博客园可以写点无关技术的帖子吗?
    RUBY元编程学习之”编写你的第一种领域专属语言“
  • 原文地址:https://www.cnblogs.com/Gloid/p/9928404.html
Copyright © 2020-2023  润新知