社区讨论

A*10pts求调

P2901[USACO08MAR] Cow Jogging G参与者 2已保存回复 2

讨论操作

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

当前回复
2 条
当前快照
1 份
快照标识符
@mhkdz3xp
此快照首次捕获于
2025/11/04 17:48
4 个月前
此快照最后确认于
2025/11/04 17:48
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
const int N = 1e3 + 10;
const int M = 1e6 + 10;

int dis[N],n,m,k;
bool vis[N];

struct node1{
	int to;
	int val;
};
struct node2
{
	int pos;
	int len;
};
bool operator < (node2 a,node2 b){
		return a.len + dis[a.pos] > b.len + dis[b.pos];//将小于定义为大于 
}

vector <node1> edge1[N];
vector <node1> edge2[N];

void SPFA()//SPFA跑的是反向图 
{  //求出所有点到终点的距离dis 
	queue <int> q;
	q.push(1);
	memset(dis,127,sizeof(dis));
	vis[1] = 1;dis[1] = 0;
	while(q.size())
	{
		int u = q.front();
		q.pop();
		vis[u] = 1;
		for(auto i : edge2[u])
		{
			if(dis[i.to] > dis[u] + i.val)
			{
				dis[i.to] = dis[u] + i.val;//正常的松弛操作 
				if(vis[i.to])
				{
					vis[i.to] = 0;
					q.push(i.to);
				}
			}
		}
	}
}
// g(x)为从起点开始的距离函数,h(x) 为到终点的距离函数 
//距离函数为起点到当前节点已经走过的距离,估价函数为从当前节点到终点至少要走过的距离(最短路) 
// 估价函数f(x) = g(x) + h(x),A*每次取出一个f最小的元素,然后更新相邻状态 
int A_star(int &ret)
{
	priority_queue <node2> q;
	q.push((node2){n,0});//初始状态入优先队列 
	while(q.size())
	{
		node2 z = q.top();//每次取出f(x) = g(x) + h(x)最小的一项 
		q.pop();
		if(z.pos == 1)//到达终点 
		{
			printf("%lld\n",z.len);//第k次达到终点就是第k短路 
			if((--ret == 0))  return 0;
		}
		int u = z.pos;
		for(auto i : edge1[u])//遍历计算所连节点的信息,也将其塞入优先队列 
		{
			q.push((node2){i.to,z.len+i.val});
		} 
	}
	return ret; //剩下的不存在 
}
signed main()
{
	scanf("%lld%lld%lld",&n,&m,&k);
	for(int i = 1;i <= m;i ++)
	{
		int u,v,w;
		scanf("%lld%lld%lld",&u,&v,&w);
		edge1[u].push_back((node1){v,w});
		edge2[v].push_back((node1){u,w});//建反向图 
	}
	SPFA();
	A_star(k);
	while(k--)
	  printf("-1\n");
	return 0;
}

回复

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

正在加载回复...