• LOJ P3953 逛公园 NOIP dp 最短路 拓扑排序


    https://www.luogu.org/problemnew/show/P3953

    开o2过了不开o2re一个点。。。写法如题

    顺便一提这道题在我校oj是a不了的因为我校土豆服务器速度奇慢1s时限

      1 // luogu-judger-enable-o2
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cmath>
      7 #include<queue>
      8 using namespace std;
      9 const int maxn=110000;
     10 int n,m,k,p;
     11 struct nod{
     12     int y,v,next;
     13 }e[2][maxn*2];
     14 int head[2][maxn]={};
     15 int dis[2][maxn]={};
     16 int d[maxn]={},zz[maxn]={};
     17 int mx,cnt=0,ans=0,tot=0;
     18 int f[60][maxn]={};
     19 bool vis[maxn]={};
     20 queue< int >q;
     21 void init(int x,int y,int v){
     22     e[0][++tot].y=y;e[0][tot].v=v;e[0][tot].next=head[0][x];head[0][x]=tot;
     23     e[1][tot].y=x;e[1][tot].v=v;e[1][tot].next=head[1][y];head[1][y]=tot;
     24 }
     25 void SPFA(int x,int z){
     26     for(int i=1;i<=n;i++)vis[i]=0;
     27     q.push(x);vis[x]=1;dis[z][x]=0;
     28     int y,v,v1;
     29     while(!q.empty()){
     30         x=q.front();q.pop();v=dis[z][x];
     31         for(int i=head[z][x];i;i=e[z][i].next){
     32             y=e[z][i].y;v1=e[z][i].v;
     33             if(dis[z][y]>v+v1){
     34                 dis[z][y]=v+v1;
     35                 if(!vis[y])q.push(y);
     36                 vis[y]=1;
     37             }
     38         }
     39         vis[x]=0;
     40     }
     41 }
     42 bool Topsort(){
     43     for(int i=1;i<=n;i++)d[i]=0;
     44     for(int i=1;i<=n;i++){
     45         for(int j=head[0][i];j;j=e[0][j].next){
     46             if(e[0][j].v+dis[0][i]==dis[0][e[0][j].y])d[e[0][j].y]++;//按照最短路连边
     47         }
     48     }cnt=0;
     49     for(int i=1;i<=n;i++)if(!d[i])zz[++cnt]=i;
     50     for(int i=1;i<=cnt;i++){
     51         for(int j=head[0][zz[i]];j;j=e[0][j].next){
     52             if(e[0][j].v+dis[0][zz[i]]==dis[0][e[0][j].y]){
     53                 d[e[0][j].y]--;
     54                 if(!d[e[0][j].y])zz[++cnt]=e[0][j].y;
     55             }
     56         }
     57     }
     58     for(int j=1;j<=n;j++){//如果有0边构成的环,那么这个环一定到最后也有d
     59         if(d[j]&&dis[0][j]+dis[1][j]<=k+dis[0][n])return 1;//如果环在合法路上就不用dp了有无数种方案
     60     }return 0;
     61 }
     62 void DP(){
     63     for(int i=0;i<=k;i++)
     64         for(int j=0;j<=n;j++)f[i][j]=0;
     65     ans=0;f[0][1]=1;
     66     int y,v,x;
     67     for(int i=0;i<=k;i++){
     68         for(int j=1;j<=cnt;j++){
     69             x=zz[j];if(dis[1][x]==mx)continue;
     70             for(int w=head[0][x];w;w=e[0][w].next){
     71                 y=e[0][w].y;v=e[0][w].v;
     72                 if(dis[0][x]+v==dis[0][y])f[i][y]=(f[i][y]+f[i][x])%p;//用拓扑序给f[k][i]汇总一下
     73             }
     74         }
     75         for(int j=1;j<=n;j++){//f[k][x]往下延伸
     76             x=j;if(dis[1][x]==mx)continue;
     77             for(int w=head[0][x];w;w=e[0][w].next){
     78                 y=e[0][w].y;v=e[0][w].v;
     79                 if(dis[0][x]+v!=dis[0][y]){
     80                     if(i+dis[0][x]+v-dis[0][y]<=k)
     81                         f[i+dis[0][x]+v-dis[0][y]][y]=(f[i+dis[0][x]+v-dis[0][y]][y]+f[i][x])%p;
     82                 }
     83             }
     84         }ans=(ans+f[i][n])%p;
     85     }
     86 }
     87 int main(){
     88     //freopen("now.in","r",stdin);
     89     int T;scanf("%d",&T);mx=(int)1e8;
     90     while(T-->0){
     91         scanf("%d%d%d%d",&n,&m,&k,&p);
     92         for(int i=0;i<=n;i++)dis[0][i]=dis[1][i]=mx;
     93         for(int i=0;i<=n;i++)head[0][i]=head[1][i]=0;tot=0;
     94         int x,y,v;
     95         for(int i=1;i<=m;i++){
     96             scanf("%d%d%d",&x,&y,&v);init(x,y,v);
     97         }
     98         SPFA(1,0);SPFA(n,1);//cout<<dis[1][1]<<dis[0][n]<<endl;
     99         if(dis[1][1]==mx)printf("0
    ");
    100         else{
    101             if(Topsort()){
    102                 printf("-1
    ");
    103             }
    104             else{
    105                 DP();
    106                 printf("%d
    ",ans);
    107             }
    108         }
    109     }
    110     return 0;
    111 }
    View Code

  • 相关阅读:
    Spring Boot 的单元测试和集成测试
    Containers vs Serverless:你选择谁,何时选择?
    Java13新特性
    Java中创建对象的5种方法
    最好的重试是指数后退和抖动
    杂谈:面向微服务的体系结构评审中需要问的三个问题
    使用Quarkus在Openshift上构建微服务的快速指南
    Java EE—最轻量级的企业框架?
    AQS机制
    JVM-内存模型
  • 原文地址:https://www.cnblogs.com/137shoebills/p/8680953.html
Copyright © 2020-2023  润新知