zoukankan      html  css  js  c++  java
  • NOIP2017 D1T3逛公园

    DP+最短路

    两遍最短路判零环

    DP转移f[i][j] 到点i的距离比最短路多j时的方案数

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int N=400005;
      4 struct node
      5 {
      6     int to,nex,w;
      7 }e[N],z[N];
      8 int cnt,cnt1,head[100005],head2[100005];
      9 int add(int x,int y,int w)
     10 {
     11     e[++cnt1].to=y;e[cnt1].w=w;e[cnt1].nex=head[x];head[x]=cnt1;
     12     z[++cnt].to=x;z[cnt].w=w;z[cnt].nex=head2[y];head2[y]=cnt;
     13 }
     14 int f[100005][51];
     15 int d1[100005],d2[100005],d[100005],qq[N<<1];
     16 bool v[100005];int n,m,k,p;
     17 void update(int &a,int b)
     18 {
     19     a=(a+b)%p;
     20 }
     21 queue<int>q;
     22 void work()
     23 {
     24     scanf("%d%d%d%d",&n,&m,&k,&p);cnt=0,cnt1=0;
     25     memset(head,0,sizeof(head));
     26     memset(head2,0,sizeof(head2));
     27     for(int i=1;i<=m;++i)
     28     {
     29         int x,y,w;
     30         scanf("%d%d%d",&x,&y,&w);
     31         add(x,y,w);
     32     }
     33     memset(v,0,sizeof(v));memset(d1,0x3f,sizeof(d1));
     34     q.push(1);d1[1]=0;v[1]=1;
     35     while(!q.empty())
     36     {
     37         int x=q.front();q.pop();v[x]=0;
     38         for(int i=head[x];i;i=e[i].nex)
     39         {
     40             int y=e[i].to;
     41             if(d1[y]>d1[x]+e[i].w)
     42             {
     43                 d1[y]=d1[x]+e[i].w;
     44                 if(!v[y])
     45                 {
     46                     q.push(y);v[y]=1;
     47                 }
     48             }
     49         }
     50     }
     51     memset(v,0,sizeof(v));memset(d2,0x3f,sizeof(d2));
     52     q.push(n);d2[n]=0;v[n]=1;
     53     while(!q.empty())
     54     {
     55         int x=q.front();q.pop();v[x]=0;
     56         for(int i=head2[x];i;i=z[i].nex)
     57         {
     58             int y=z[i].to;
     59             if(d2[y]>d2[x]+z[i].w)
     60             {
     61                 d2[y]=d2[x]+z[i].w;
     62                 if(!v[y])
     63                 {
     64                     q.push(y);v[y]=1;
     65                 }
     66             }
     67         }
     68     }
     69     
     70     int top=0;memset(d,0,sizeof(d));
     71     for(int i=1;i<=n;++i)
     72     for(int j=head[i];j;j=e[j].nex)
     73     {
     74         if(d1[i]+e[j].w==d1[e[j].to])d[e[j].to]++;
     75     }
     76     for(int i=1;i<=n;++i)if(!d[i])qq[++top]=i;
     77     for(int i=1;i<=top;++i)
     78     {
     79         int x=qq[i];
     80         for(int j=head[x];j;j=e[j].nex)
     81         if(d1[x]+e[j].w==d1[e[j].to])
     82         {
     83             int y=e[j].to;
     84             d[y]--;
     85             if(d[y]==0)qq[++top]=y;
     86         }
     87     }
     88     for(int i=1;i<=n;++i)
     89     if(d[i]&&d1[i]+d2[i]<=d1[n]+k)
     90     {
     91         puts("-1");return;
     92     }
     93     int ans=0;
     94     memset(f,0,sizeof(f));
     95     f[1][0]=1;
     96     for(int i=0;i<=k;++i)
     97     {
     98         for(int j=1;j<=top;++j)
     99         for(int u=head[qq[j]];u;u=e[u].nex)
    100         {
    101             if(d1[qq[j]]+e[u].w==d1[e[u].to])
    102             update(f[e[u].to][i],f[qq[j]][i]);
    103         }
    104         
    105         for(int j=1;j<=n;++j)
    106         for(int u=head[j];u;u=e[u].nex)
    107         {
    108             if(d1[j]+e[u].w!=d1[e[u].to]&&i+d1[j]-d1[e[u].to]+e[u].w<=k)
    109             update(f[e[u].to][i+d1[j]-d1[e[u].to]+e[u].w],f[j][i]);
    110         }
    111     }
    112     for(int i=0;i<=k;++i)
    113     update(ans,f[n][i]);
    114     printf("%d\n",ans);
    115     return ;
    116 }
    117 int main()
    118 {
    119     int t;scanf("%d",&t);
    120     while(t--)
    121     {
    122         work();
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    设计模式:备忘录模式(Memento)
    设计模式:中介者模式(Mediator)
    设计模式:迭代器模式(Iterator)
    设计模式:解释器模式(Interpreter)
    设计模式:命令模式(Command)
    设计模式:职责链模式(Chain of Responsibility)
    设计模式:单例模式(单例模式)
    win7硬盘安装方法
    sqlite 附加和分离数据库
    Sqlite 复制表结构和数据
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/7912293.html
Copyright © 2011-2022 走看看