sgu145:Strange People

题意很简单,就是要求第k短路。

看网上好多人都是用dfs+二分过的,我果断作死写了个dijstra+A*。

但最坑的是这道题竟然标程都PE,估计sgu数据坑...

代码正确性应该还是有的,还是贴贴吧。

<pre name="code" class="cpp">#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 105, INF = 1e9;
int n = 0, m = 0, k = 0, s = 0, e = 0;
int mtx[MAXN][MAXN] = {0};
struct node{int x, g, h, pd[4];};
int dis[MAXN] = {0};
bool used[MAXN] = {0};
int ans = 0, time[MAXN] = {0};

bool operator < (const node &A, const node &B)
{
	if((A.g+A.h) == (B.g+B.h)) return A.g > B.g;
	else return (A.g+A.h) > (B.g+B.h);	
}	

void dijstra()
{
	for(int i = 1; i <= n; ++i)
		dis[i] = INF;
	dis[e] = 0;
	int cur = e;
	for(int i = 1; i <= n; ++i)
	{
		used[cur] = true;
		for(int j = 1; j <= n; ++j)
			if(!used[j] && dis[j] > dis[cur]+mtx[cur][j])
				dis[j] = dis[cur]+mtx[cur][j];
		int minv = INF, minf = 0;
		for(int j = 1; j <= n; ++j)
			if(!used[j])
				if(minv > dis[j])
				{
					minv = dis[j];
					minf = j;	
				}
		cur = minf;
	}
}

void A_star()
{
	priority_queue<node> q;	
	node tmp = {s, 0, dis[s], {0}};
	tmp.pd[0] += 1<<(s-1);
	q.push(tmp);
	while(!q.empty())
	{
		node T = q.top();
		q.pop();
		time[T.x]++;
		if(time[T.x] >= k)
		{
			if(T.x == e)
			{
				ans = T.g+T.h;
				printf("%d", ans);
				return ;
			}
			if(time[T.x] > k)
				continue;
		}
		for(int i = 1; i <= n; ++i)
		{
			if(mtx[T.x][i])
			{
				tmp = T;//二进制是为了判断不能走重复的点。
				if(i <= 30)
				{
					if(T.pd[0]&(1<<(i-1)))
						continue;
					else tmp.pd[0] += 1<<(i-1);
				}
				else if(i > 30 && i <= 60)
				{
					if(T.pd[1]&(1<<(i-31)))
						continue;
					else tmp.pd[1] += 1<<(i-31);
				}
				else if(i > 60 && i <= 90)
				{
					if(T.pd[2]&(1<<(i-61)))
						continue;
					else tmp.pd[2] += 1<<(i-61);
				}
				else 
				{
					if(T.pd[3]&(1<<(i-91)))
						continue;
					else tmp.pd[3] += 1<<(i-91);	
				}
				tmp.x = i;
				tmp.g = T.g+mtx[T.x][i];
				tmp.h = dis[i];
				q.push(tmp);
			}
		}
	}
}

int path[MAXN] = {0}, top = 0;
bool flag = false;
void dfs(int cur, int d)
{
	if(d > ans || flag) return ;
	path[++top] = cur;
	used[cur] = true;
	if(cur == e && d == ans)	
	{
		printf(" %d\n", top);
		if(top >= 1)	
			printf("%d", path[1]);
		for(int i = 2; i <= top; ++i)	
			printf(" %d", path[i]);
		flag = true;
		return ;
	}
	for(int i = 1; i <= n; ++i)
		if(!used[i] && mtx[cur][i])	
			dfs(i, d+mtx[cur][i]);
	path[top--] = 0;
	used[cur] = false;
}

int main()
{
	scanf("%d%d%d", &n, &m, &k);
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
			if(i != j) mtx[i][j] = INF;
	for(int i = 1; i <= m; ++i)
	{
		int x, y, z;
		scanf("%d%d%d", &x, &y, &z);
		mtx[x][y] = mtx[y][x] = z;	
	}
	scanf("%d%d", &s, &e);
	if(s == e) k++;
	
	dijstra();
	
	A_star();
	
	memset(used, false, sizeof(used));
	dfs(s, 0);
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
疫情居家办公系统管理系统按照操作主体分为管理员和用户。管理员的功能包括办公设备管理、部门信息管理、字典管理、公告信息管理、请假信息管理、签到信息管理、留言管理、外出报备管理、薪资管理、用户管理、公司资料管理、管理员管理。用户的功能等。该系统采用了MySQL数据库,Java语言,Spring Boot框架等技术进行编程实现。 疫情居家办公系统管理系统可以提高疫情居家办公系统信息管理问题的解决效率,优化疫情居家办公系统信息处理流程,保证疫情居家办公系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理疫情居家办公系统信息,包括外出报备管理,培训管理,签到管理,薪资管理等,可以管理公告。 外出报备管理界面,管理员在外出报备管理界面中可以对界面中显示,可以对外出报备信息的外出报备状态进行查看,可以添加新的外出报备信息等。签到管理界面,管理员在签到管理界面中查看签到种类信息,签到描述信息,新增签到信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值