社区讨论
求助dalao,此题A*怎么做
P3953[NOIP 2017 提高组] 逛公园参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mi7perc5
- 此快照首次捕获于
- 2025/11/21 01:27 4 个月前
- 此快照最后确认于
- 2025/11/21 01:27 4 个月前
RT,A*只有30分
代码如下
CPP#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
#define re register
#define isnum(x) (x<58&&x>47)
inline int read(){
int ans=0,v=1;
char ch=getchar();
while(!isnum(ch)&&ch^45)ch=getchar();
if(!(ch^45))v=-1,ch=getchar();
while(isnum(ch))ans=(ans<<1)+(ans<<3)+ch-48,ch=getchar();
return ans*v;
}
const int maxn=100001;
const int maxm=200001;
const int INF=2147383467;
struct edge{
int nxt,to,w;
}E[maxm];
int n,m,k,P;
int cnt,ans;
int x[maxm],y[maxm],z[maxm];
int head[maxn],dis[maxn],vis[maxn];
inline void add(int u,int v,int w){
cnt++;
E[cnt].to=v;
E[cnt].nxt=head[u];
E[cnt].w=w;
head[u]=cnt;
}
inline void dijkstra(){
for(re int i=1;i<=n;i++)
dis[i]=INF;
dis[n]=0;
// vis[n]=1;
queue<int>q;
q.push(n);
while(!q.empty()){
int v=q.front();
q.pop();
//printf("%d\n",v);
for(re int i=head[v];i;i=E[i].nxt){
int u=E[i].to,d=E[i].w;
if(dis[u]>dis[v]+d){
dis[u]=dis[v]+d;
//printf("%d %d\n",u,dis[u]);
// if(!vis[u]){
// vis[u]=1;
q.push(u);
// }
}
}
}
}
struct node{
int to,f,g;
bool operator <(const node a) const {
if(a.f^f)return f>a.f;
return g>a.g;
}
};
inline void A_star(){
node temp;
temp.to=1;
temp.g=0;
temp.f=dis[1];
priority_queue<node>q;
q.push(temp);
while(!q.empty()){
node tmp=q.top();
q.pop();
int u=tmp.to;
// printf("%d\n",u);
if(!(u^n)){
ans++;
ans%=P;
printf("%d\n",ans);
if(dis[1]+k<tmp.g)return ;
}
for(re int i=head[u];i;i=E[i].nxt){
// printf("%d\n",E[i].to);
temp.to=E[i].to;
temp.g=tmp.g+E[i].w;
temp.f=temp.g+dis[temp.to];
q.push(temp);
}
// getchar();
}
}
int T;
int main(){
freopen("f:/testdata.in","r",stdin);
T=read();
while(T--){
ans=0;
cnt=0;
memset(head,0,maxn<<2);
n=read();m=read();k=read();P=read();
for(re int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add(v,u,w);
x[i]=u;y[i]=v;z[i]=w;
}
for(re int i=1;i<=m;i++){
// int v=0;
if(!z[i])
for(re int j=y[i];!z[j];j=y[j]){
if(!(x[i]^x[j])){
puts("-1");
break;
}
}
}
dijkstra();
/* for(re int i=1;i<=n;i++)
printf("%d %d\n",i,dis[i]);*/
cnt=0;
memset(head,0,maxn<<2);
for(re int i=1;i<=m;i++){
add(x[i],y[i],z[i]);
}
A_star();
printf("%d\n",ans-1);
}
fclose(stdin);
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...