P3953 逛公园

Posted sfwr-you

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3953 逛公园相关的知识,希望对你有一定的参考价值。

技术图片

______________________________________________________________________________________________________

绝望题目,一点一点从30--70--100,打完了所有部分分

【大部分时间都在查错

——————————————————————————————————————————————————

#include <bits/stdc++.h>
using namespace std;
#define setfax(x) memset(x, 0x3f, sizeof(x));
#define setfin(x) memset(x, 0, sizeof(x));
int n,m,ne,ne0,ans,flg,t,a,b,c,dis[100100],nef,vist[100100],p,k;
int f[100100][51],head[100100],head0[100100],rd[100100],qr[100100],headf[100100],disf[100100];
struct node int to, dis, nxt; eg[200100], egf[200100];
struct nodint to,nxt;eg0[200100];
struct nd int id, dis,ft; num[100100];
int cmp(nd x, nd y)  return x.dis==y.dis?x.ft<y.ft:x.dis<y.dis;
int cmp2(nd x, nd y)  return x.dis<y.dis;
void adde(int u,int v,int c)eg[++ne].to=v;eg[ne].dis=c;eg[ne].nxt=head[u];head[u]=ne;
void addef(int u,int v,int c)egf[++nef].to=v;egf[nef].dis=c;egf[nef].nxt=headf[u];headf[u]=nef;
void add0(int u,int v)eg0[++ne0].to=v;eg0[ne0].nxt=head0[u];head0[u]=ne0;rd[v]++;
void spfa() 
    setfin(vist);queue<int> q;q.push(1);vist[1]=1;dis[1]=0;
    while (!q.empty()) 
        int u=q.front();q.pop();vist[u]=0;
        for (int i = head[u]; i; i = eg[i].nxt) 
            int v = eg[i].to;
            if (dis[v] > eg[i].dis + dis[u]) 
            dis[v] = eg[i].dis + dis[u];
            if (!vist[v]) vist[v] = 1;q.push(v);
        
    

void spfaf() 
    queue<int> q;setfin(vist);q.push(n);vist[n]=1;disf[n]=0;
    while (!q.empty()) 
        int u=q.front();q.pop();vist[u]=0;
        for (int i=headf[u];i;i=egf[i].nxt) 
            int v = egf[i].to;
            if (disf[v]>egf[i].dis+disf[u]) 
            disf[v]=egf[i].dis+disf[u];
            if (!vist[v])vist[v]=1;q.push(v);
        
    

int topo()
    
    int l=1,r=0;
    for(int i=1;i<=n;i++)if(!rd[i])qr[++r]=i;
    while(l<=r)
    for(int i=head0[qr[l++]];i;i=eg0[i].nxt)
    if(!--rd[eg0[i].to])qr[++r]=eg0[i].to;
    for(int i=1;i<=n;i++)num[qr[i]].ft=i;
    for(int i=1;i<=n;i++)if(rd[i]&&(dis[i]+disf[n]<=dis[n]+k))return 1;
    return 0;

void cl() 
    ans=0;ne = 0;nef = 0;ne0=0;flg=0;
    setfax(dis);setfax(disf);
    setfin(head);setfin(head0);setfin(headf);
    setfin(eg);setfin(egf);setfin(eg0);
    setfin(f);setfin(qr);setfin(num);setfin(rd);
    f[1][0] = 1;

void solve()
        for (int j = 0; j <= k; j++)
        for (int s = 1; s <= n; s++) 
            int u = num[s].id;
            if (disf[u] == 0x3f3f3f3f)continue;
            for (int nx = head[u]; nx; nx = eg[nx].nxt)
                 
                    int v = eg[nx].to;
                    if (disf[v] == 0x3f3f3f3f)continue;
                    if (dis[u] - dis[v] + j + eg[nx].dis <= k)
                        f[v][dis[u] - dis[v] + j + eg[nx].dis] =
                            (f[v][dis[u] - dis[v] + j + eg[nx].dis] + f[u][j]) % p;
                
        

int main() 
    cin >> t;
    while (t--) 
        scanf("%d%d%d%d",&n,&m,&k,&p);
        cl();
        while (m--) scanf("%d%d%d",&a,&b,&c);adde(a, b, c);addef(b, a, c);if(!c)flg=1;add0(a,b);
        spfa();spfaf();
        for (int i = 1; i <= n; i++) num[i].id = i;num[i].dis = dis[i];
        if(!flg)sort(num + 1, num + 1 + n, cmp2);
        elseif(topo())cout<<-1<<endl;continue;sort(num+1,num+1+n,cmp);
        solve();
        for (int j=0;j<=k;j++)ans=(ans+f[n][j])%p;cout<<ans<<endl;
    

 

以上是关于P3953 逛公园的主要内容,如果未能解决你的问题,请参考以下文章

P3953 逛公园

[luogu P3953] [noip2017 d1t3] 逛公园

Luogu P3953NOIP2017逛公园最短路+拓扑排序+动态规划

P3953 NOIP2017 d1t3 逛公园

P3953 逛公园

[Luogu P3953] 逛公园 (最短路+拓扑排序+DP)