社区讨论
全RE求助
P3953[NOIP 2017 提高组] 逛公园参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lwdd4v2d
- 此快照首次捕获于
- 2024/05/19 17:56 2 年前
- 此快照最后确认于
- 2024/05/19 20:30 2 年前
第一次提交因为没有把答案清零导致只过了3个hack数据其他7个WA 3个TLE,第二次提交把答案清零了但是直接全RE,但是下的样例就能正常过,调了很久都没有调试好,现在依然很疑惑。求大佬相助,悬赏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");
else
printf("%d\n",ans);
}
return 0;
}
具体思路是先Dijkstra求最小路,然后再一遍dp求最小路,最后dp求合法道路数量
回复
共 0 条回复,欢迎继续交流。
正在加载回复...