社区讨论

全RE求助

P3953[NOIP 2017 提高组] 逛公园参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lwap3ns5
此快照首次捕获于
2024/05/17 21:08
2 年前
此快照最后确认于
2024/05/17 21:08
2 年前
查看原帖
第一次没有在主函数里把答案归零所以只过了3个hack数据,第二三次加了归零后就全RE了,但是下的样例4就能正常过。自己调试也调不对,求大佬调试一下,悬赏1个关注。代码如下:
CPP
#include<bits/stdc++.h>
#define mk make_pair
using namespace std;
const int maxn=100010;
struct Edge{
	int v,w;//u这个点所指向的所有点和其长度; 
};
vector <Edge> tu1[maxn],tu2[maxn];//正图和反图
bool done[maxn];//到该点的最小路是否找到 ;
bool vis[maxn][51];//是否访问过(判断环);
int n,m,k,p;
int T;
int dis[maxn];//最小路;
int f[maxn][51];//到i的小于最小路+k的个数;
bool huan0;
bool zuixiaolu(){
	memset(done,false,sizeof(done));
	memset(dis,0x3f,sizeof(dis));
	priority_queue<pair<int,int> > q;
	q.push(mk(0,1));
	dis[1]=0;
	while(!q.empty()){
		int u=q.top().second;
		q.pop();
		if(done[u]==true) continue;
		else done[u]=true;
		vector<Edge>::iterator it;
		for(it=tu1[u].begin();it!=tu1[u].end();it++){
			int v=it->v,w=it->w;
			if(dis[v]>dis[u]+w){
				dis[v]=dis[u]+w;
				q.push(mk(-dis[v],v));
			}
		}
	}
}
int dfs(int u,int k){
	if(k<0)
		return 0;
	if(vis[u][k]){
		huan0=true;	
		return 0;	
	}
	if(f[u][k]>0)
		return f[u][k];
	vis[u][k]=true;
	vector<Edge>::iterator it;
	int cnt=0;
	for(it=tu2[u].begin();it!=tu2[u].end();it++){
		int v=it->v,w=it->w;
		cnt=(cnt+dfs(v,dis[u]-dis[v]+k-w))%p;
		if(huan0) 
			return 0;
	}
	vis[u][k]=0;
	return f[u][k]=cnt;
}
int main(){
	scanf("%d",&T);
	while(T--){
		huan0=false;
		memset(f,0,sizeof(f));
		memset(vis,false,sizeof(vis));
		scanf("%d%d%d%d",&n,&m,&k,&p);
		for(int i=1;i<=n;i++){
            tu1[i].clear();
			tu2[i].clear();
        }
		for(int i=1;i<=m;i++){
			int u,v,w;
			scanf("%d%d%d",&u,&v,&w);
			tu1[u].push_back((Edge){v,w});
			tu2[v].push_back((Edge){u,w});
		}
		zuixiaolu();
		dfs(1,0);
		f[1][0]=1;
		int ans=0;
		for(int i=0;i<=k;i++)
			ans+=dfs(n,i)%p;
		if(huan0)
			printf("-1\n",ans);
		else
			printf("%d\n",ans);
	}
	return 0;
} 
有些抽象
具体思路是先Dijkstra后查找最小路最后dp

回复

0 条回复,欢迎继续交流。

正在加载回复...