P3953 逛公园

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 nod{int 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);
        else{if(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;
    }
}

 

上一篇:432D Prefixes and Suffixes


下一篇:p2501 [HAOI2006]数字序列