• Luogu3953 NOIP2017逛公园(最短路+拓扑排序+动态规划)


      跑一遍dij根据最短路DAG进行拓扑排序,按拓扑序dp即可。wa了三发感觉非常凉。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    #define ll long long
    #define N 100010
    #define M 200010 
    #define K 51
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) 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 T,n,m,k,P,p[N],d[N],from[M],f[N][K],Q[N],degree[N],t;
    bool flag[N];
    struct data{int to,nxt,len;
    }edge[M];
    struct data2
    {
        int x,d;
        bool operator <(const data2&a) const
        {
            return d>a.d;
        }
    };
    priority_queue<data2> q;
    void inc(int &x,int y){x+=y;if (x>=P) x-=P;}
    void addedge(int x,int y,int z){t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z;p[x]=t;}
    void dijkstra()
    {
        memset(d,42,sizeof(d));d[1]=0;
        memset(flag,0,sizeof(flag));
        q.push((data2){1,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]});
            }
        }
    }
    bool topsort()
    {
        memset(degree,0,sizeof(degree));
        for (int i=1;i<=m;i++) 
        if (d[from[i]]+edge[i].len==d[edge[i].to]) degree[edge[i].to]++;
        int head=0,tail=0;for (int i=1;i<=n;i++) if (!degree[i]) Q[++tail]=i;
        while (head<tail&&tail<n)
        {
            int x=Q[++head];
            for (int i=p[x];i;i=edge[i].nxt)
            if (d[x]+edge[i].len==d[edge[i].to])
            {
                degree[edge[i].to]--;
                if (!degree[edge[i].to]) Q[++tail]=edge[i].to;
            }
        }
        return tail<n;
    }
    int main()
    {
        T=read();
        while (T--)
        {
            n=read(),m=read(),k=read(),P=read();
            t=0;memset(p,0,sizeof(p));
            for (int i=1;i<=m;i++)
            {
                int x=read(),y=read(),z=read();
                from[i]=x;addedge(x,y,z);
            }
            dijkstra();
            if (topsort()) cout<<-1<<endl;
            else
            {
                memset(f,0,sizeof(f));f[1][0]=1;
                for (int i=0;i<=k;i++)
                    for (int j=1;j<=n;j++)
                    {
                        int x=Q[j];
                        for (int y=p[x];y;y=edge[y].nxt)
                        {
                            int u=d[x]+edge[y].len-d[edge[y].to]+i;
                            if (u<=k) inc(f[edge[y].to][u],f[x][i]);
                        }
                    }
                int ans=0;
                for (int i=0;i<=k;i++) inc(ans,f[n][i]);
                cout<<ans<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    记laravel项目,本地环境PHP7.1,线上PHP版本7.2,报错each函数废弃问题
    [教程] 《Mysql 实战 45 讲》
    PHP递归求和计算1加到n的和
    SSL原理
    PHP之抽象类与接口
    iOS调试之挂起线程
    iOS之Starfield
    iOS之透视效果
    CSS之框模型
    HTTP之CacheControl
  • 原文地址:https://www.cnblogs.com/Gloid/p/9931408.html
Copyright © 2020-2023  润新知