• noip2017逛公园


    题解:

    之前知道正解并没有写过。。

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define me(x) memset(x,0,sizeof(x))
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
      return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T>void read(T &x)
    {
      rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
      while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
    }
    const int N=3e5;
    struct re{
      int a,b,c;
    }e[N],jl[N];
    int n,m,k,p,head[N],l,rd[N],tim[N];
    void arr(int x,int y,int z)
    {
      e[++l].a=head[x];
      e[l].b=y;
      e[l].c=z;
      head[x]=l;
    }
    queue<int> q;
    stack<int> S;
    int dfn[N],low[N],col[N],color_cnt,sz[N],cnt,tim2[N];
    bool ins[N];
    void tarjan(int x,int y)
    {
      dfn[x]=low[x]=++cnt; S.push(x); ins[x]=1;
      for (rint u=head[x];u;u=e[u].a)
      {
        rint v=e[u].b;
          if (!dfn[v])
          {
            tarjan(v,x);
            dfn[x]=min(dfn[x],low[v]);
          }
          if (ins[v]) dfn[x]=min(dfn[x],dfn[v]);
      }
      if (dfn[x]==low[x])
      {
        color_cnt++;
        while (1) 
        {
          int y=S.top(); S.pop(); col[y]=color_cnt; ins[y]=0; sz[color_cnt]++;
          if (y==x) break;
        }
      }
    }
    const int INF=5e8;
    int dis[N],dis1[N],dis2[N];
    struct cmp{
      bool operator () (re x,re y)
      {
        return x.b>y.b;
      }
    };
    priority_queue<re,vector<re>,cmp> Q;
    bool vis[N];
    void dij(int x)
    {
      me(vis);
      rep(i,1,n) dis[i]=INF;
      Q.push((re){x,0}); dis[x]=0;
      while (!Q.empty())
      {
        int x=Q.top().a; Q.pop();
        if (vis[x]) continue; vis[x]=1;
        for (rint u=head[x];u;u=e[u].a)
        {
          int v=e[u].b;
          if (dis[v]>dis[x]+e[u].c)
          {
            dis[v]=dis[x]+e[u].c;
            Q.push((re){v,dis[v]});
          }
        }
      }
    }
    int f[N][52];
    const int N2=1.5e7;
    re ve[N2];
    IL void js(int &x,int y)
    {
      x=(x+y)%p;
    }
    bool cmp3(re y,re x)
    {
      int jl1=dis1[x.a]+x.b;
      int jl2=dis1[y.a]+y.b;
      return (jl2<jl1)||(jl1==jl2&&tim[y.a]<tim[x.a]);
    }
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      int T;
      read(T);
      rep(ttt,1,T)
      {
        l=0; me(head); me(dfn); me(low); me(sz); color_cnt=0;
        read(n); read(m); read(k); read(p);  me(rd);
        rep(i,1,m)
        {
          int x,y,z;
          read(x); read(y); read(z);
          jl[i]=(re){x,y,z};
          if (z==0) arr(x,y,z),rd[y]++;
        }
        rep(i,1,n) if (!rd[i]) q.push(i);
        int cnt=0;
        while (!q.empty())
        {
           int x=q.front(); q.pop(); tim[x]=++cnt;
           for (rint u=head[x];u;u=e[u].a)
           {
             rint v=e[u].b;
             rd[v]--;
             if (!rd[v]) q.push(v);
           }
        }
        rep(i,1,n) if (!dfn[i]) tarjan(i,0);
        me(head); l=0;
        int s=col[1],t=col[n];
        rep(i,1,m)
          if (col[jl[i].a]!=col[jl[i].b]) arr(col[jl[i].a],col[jl[i].b],jl[i].c);
        dij(s);
        rep(i,1,n) dis1[i]=dis[i];
        me(head); l=0;
        rep(i,1,m)
          if (col[jl[i].a]!=col[jl[i].b]) arr(col[jl[i].b],col[jl[i].a],jl[i].c);
        dij(t);
        rep(i,1,n) dis2[i]=dis[i];
        int now=dis1[n];
        bool tt=0;
        rep(i,1,color_cnt)
          if (dis1[i]+dis2[i]<=now+k&&sz[i]>1) tt=1;
        if (tt)
        {
          cout<<-1<<endl;
          continue;
        }
        me(head); l=0;
        rep(i,1,m)
          if (col[jl[i].a]!=col[jl[i].b]) arr(col[jl[i].a],col[jl[i].b],jl[i].c);
        int ans=0;
        me(f);
        f[s][0]=1;
        rep(i,1,n) tim2[col[i]]=tim[i];
        rep(i,1,n) tim[i]=tim2[i];
        int cnt2=0;
        rep(i,1,color_cnt)
          rep(j,0,50)
            if (dis1[i]+dis2[i]+j<=now+k)
            { 
              ve[++cnt2]=(re){i,j};
            }
        sort(ve+1,ve+cnt2+1,cmp3);
        rep(i,1,cnt2)
        {
          re xx=ve[i];
          int x=xx.a,y=xx.b;
          if (!f[x][y]) continue;
          if (x==t) ans=(ans+f[x][y])%p;
          for (rint u=head[x];u;u=e[u].a)
          {
            rint v=e[u].b;
            if (e[u].c+y+dis1[x]+dis2[v]<=now+k)
            {
              int t1=f[v][e[u].c+y+dis1[x]-dis1[v]],t2=f[x][y];
              js(t1,t2);
              f[v][e[u].c+y+dis1[x]-dis1[v]]=t1;
            }
          }
        }
        cout<<ans<<endl;
      }
      return 0;
    }
    View Code

    我觉得这细节真的挺多的。。

    而且我都不知道我去年怎么写的60分了。。

    网上的方法好像比我的简单。。。

    首先在0环上我的处理是

    先缩点,然后判缩完后的点能否在路径上

    如果能在,输出-1

    由于这个缩点还是带来了比较大的干扰。。

    调试中的几个错都是这个产生的。。

    另外最短路据说是线段树优化跑的最快??

    最后的dp还是比较简单的

    f[i][j]表示到i点,比原先最短路长j,然后对终点跑一遍最短路来剪枝

    然后发现相同dis可以互相转移

    所以根据零边拓扑排序一下

    网上的判0环的方法比较简单

    直接在做的时候 如果扩展到之前的状态 就说明有0环

    这很显然啊。。。。

    主要刚开始没仔细想这个过程。。

    noip至少得留1:30 才能搞完这题吧。。 2:00就比较稳

    诶网上最简单的代码好简单啊。。。

    直接对s跑一遍最短路,然后直接dp 省掉所有过程啊 而且还挺快的。。。(看来这个剪枝作用也不是很大)

     所以下次还是想清楚再写。。。 看看有没有简单的办法

    要是写后面这份代码 1小时足够了啊。。。

  • 相关阅读:
    随想24:中国终将发展成第一强国
    随想23:所见的并不一定是真实
    工作4年之后对人性、社会的疯言
    随想22:出路
    开源视频会议bigbluebutton开发(3)——架构体系图
    开源视频会议bigbluebutton开发(2)——配置命令工具
    开源视频会议bigbluebutton开发(1)——初始化安装以及配置
    视频会议之BigBlueButton
    26款 网络会议/视频会议开源软件
    Tomcat 7最大并发连接数的正确修改方法
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9912426.html
Copyright © 2020-2023  润新知