社区讨论
后5个点re(方法是题解中的),求大佬。。。
P3953[NOIP 2017 提高组] 逛公园参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @mi6z1tfd
- 此快照首次捕获于
- 2025/11/20 13:09 4 个月前
- 此快照最后确认于
- 2025/11/20 13:09 4 个月前
CPP
#include<stdio.h>
#include<string.h>
int n,m,k,p;
int f[100050][105],dis[100050],first[100050],next[200050],v[200050],w[200050];
int first2[100050],next2[200050],v2[200050],w2[200050];
bool book[100050][105]={0};
void init()
{
memset(dis,0x7f,sizeof(dis));
memset(first,-1,sizeof(first));
memset(first2,-1,sizeof(first2));
memset(next,-1,sizeof(next));
memset(next2,-1,sizeof(next2));
memset(f,-1,sizeof(f));
}
int dp(int root,int rest)
{
int rr,j,ans,i;
ans=0;
if(rest>k||rest<0) return 0;
if(book[root][rest]==1)
{
book[root][rest]=0;
return -1;
}
if(f[root][rest]!=-1) return f[root][rest];
book[root][rest]=1;
j=first2[root];
while(j!=-1)
{
i=dp(v2[j],dis[root]+rest-dis[v2[j]]-w2[j]);
if(i==-1)
{
book[root][rest]=0;
return -1;
}
ans=(ans+i)%p;
j=next2[j];
}
book[root][rest]=0;
if(root==1&&rest==0) ans++;
f[root][rest]=ans;
return ans;
}
int work()
{
int u,i,head,tail,j,ans;
int q[2050],pan[1050]={0};
ans=0;
init();
scanf("%d%d%d%d",&n,&m,&k,&p);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v[i],&w[i]);
w2[i]=w[i];
v2[i]=u;
next2[i]=first2[v[i]];
first2[v[i]]=i;
next[i]=first[u];
first[u]=i;
}
head=tail=0;q[0]=1;dis[1]=0;
while(head<=tail)
{
j=first[q[head]];
while(j!=-1)
{
if(dis[v[j]]>dis[q[head]]+w[j])
{
dis[v[j]]=dis[q[head]]+w[j];
if(pan[v[j]]==0)
{
q[++tail]=v[j];
pan[v[j]]=1;
}
}
j=next[j];
}
head++;
pan[q[head]]=0;
}
for(i=0;i<=k;i++)
{
j=dp(n,i);
if(j==-1) return -1;
ans=(ans+j)%p;
}
return ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t>0)
{
t--;
printf("%d\n",work());
}
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...