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 逛公园的主要内容,如果未能解决你的问题,请参考以下文章
[luogu P3953] [noip2017 d1t3] 逛公园