社区讨论

后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 条回复,欢迎继续交流。

正在加载回复...