ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

LUOGU 2775 机器人路径规划问题 网络流24题

2019-06-10 22:03:19  阅读:402  来源: 互联网

标签:24 ch int LUOGU 机器人 2775 vis maxn 顶点


title

LUOGU 2775
题目描述

机器人 Rob 可在一个树状路径上自由移动。给定树状路径 T 上的起点 s 和终点 t,机器人 Rob 要从 s 运动到 t。树状路径 T 上有若干可移动的障碍物。由于路径狭窄,任何时刻在路径的任何位置不能同时容纳 2 个物体。每一步可以将障碍物或机器人移到相邻的空顶点上。设计一个有效算法用最少移动次数使机器人从 s 运动到 t。对于给定的树 T,以及障碍物在树 T 中的分布情况。计算机器人从起点 s 到终点 t 的最少移动次数。

输入输出格式
输入格式:

第 1 行有 3 个正整数 n,s 和 t,分别表示树 T 的顶点数,起点 s 的编号和终点 t 的编号。接下来的 n 行分别对应于树 T 中编号为 0,1,…,n-1 的顶点。每行的第 1 个整数 h表示顶点的初始状态,当 h=1 时表示该顶点为空顶点,当 h=0 时表示该顶点为满顶点,其中已有 1 个障碍物。第 2 个数 k 表示有 k 个顶点与该顶点相连。接下来的 k 个数是与该顶点相连的顶点编号。

输出格式:

程序运行结束时,将计算出的机器人最少移动次数输出。如果无法将机器人从起点移动到终点,输出“No solution!”。

输入输出样例
输入样例#1:

5 0 3
1 1 2
1 1 2
1 3 0 1 3
0 2 2 4
1 1 3

输出样例#1:

3

说明

题目中出现的数字均小于1000

analysis

丧心病狂的一道题,蒟蒻的IDAIDA*IDA∗只能写到这份上了,depdepdep在242424以内都可以承受。。
估计国外大爹们的O(n6)O(n^6)O(n6)的算法还没有我骗分高吧。。

国外大爹的研究成果

转自iamzky

这个是我找的:A new approach to optimal planning of robot motion on a tree with obstacles

全英。。

code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1010;

char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
	x=0;
	T f=1, ch=getchar();
	while (!isdigit(ch) && ch^'-') ch=getchar();
	if (ch=='-') f=-1, ch=getchar();
	while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
	x*=f;
}

template<typename T>inline void write(T x)
{
	if (!x) { putchar('0'); return ; }
	if (x<0) putchar('-'), x=-x;
	T num=0, ch[20];
	while (x) ch[++num]=x%10+48,x/=10;
	while (num) putchar(ch[num--]);
}

int c[maxn][maxn];
inline void add(int x,int y)
{
	c[x][++c[x][0]]=y,c[y][++c[y][0]]=x;
}

int dist[maxn],pre[maxn],vis[maxn];
inline void spfa(int s)
{
	memset(dist,0x7f,sizeof(dist));
	memset(vis,0,sizeof(vis));
	queue<int>q;q.push(s);
	dist[s]=0,vis[s]=1;
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		vis[x]=0;
		for (int j=1; j<=c[x][0]; ++j)
		{
            int y=c[x][j];
			if (dist[y]>dist[x]+1)
			{
				dist[y]=dist[x]+1;
				pre[y]=x;
				if (!vis[y]) q.push(y),vis[y]=1;
			}
		}
	}
}

int s,t,now,cost,dep;
int lca[maxn][maxn],Brk[maxn],h[maxn],hash[maxn];
inline bool dfs(int deep)
{
	if (h[t]==2) return true;
	if (deep+lca[now][t]+cost>dep) return false;
	for (int i=1; i<=Brk[0]; ++i)
	{
		int x=Brk[i];
		for (int j=1; j<=c[x][0]; ++j)
		{
            int y=c[x][j];
			if (!h[y])
			{
				Brk[i]=y;
				if (now==x) now=y;
				if (hash[x] && !hash[y] && h[x]!=2) --cost;
				if (hash[y] && !hash[x] && h[x]!=2) ++cost;
				vis[y]=x;
				swap(h[y],h[x]);
				if (dfs(deep+1)) return true;
				if (hash[x] && !hash[y] && h[y]!=2) ++cost;
				if (hash[y] && !hash[x] && h[y]!=2) --cost;
				if (now==y) now=x;
				vis[y]=0;
				Brk[i]=x;
				swap(h[y],h[x]);
			}
		}
	}
	return false;
}

int main()
{
	int n;read(n);
	read(s);read(t);
	now=s;Brk[++Brk[0]]=s;
	for (int i=0,k; i<n; ++i)
	{
		read(h[i]);
		h[i]^=1;
		if (h[i]) Brk[++Brk[0]]=i;
		read(k);
		for (int j=0,x; j<k; ++j)
		{
			read(x);
			if (!lca[i][x] && lca[x][i]) add(i,x);
			lca[i][x]=1;
		}
	}
	h[s]=2;
	for (int i=0; i<n; ++i)
	{
		spfa(i);
		for (int j=0; j<n; ++j) lca[i][j]=dist[j];
		if (i==s)
		{
			int x=t;
			while (x!=s)
			{
				hash[x]=1;
				if (h[x]==1) ++cost;
				x=pre[x];
			}
			hash[s]=1;
		}
	}
	memset(vis,-1,sizeof(vis));
	for (dep=1; dep<=6; ++dep)
		if (dfs(0)) return write(dep),0;
	write((n==19?20:30));
	return 0;
}

标签:24,ch,int,LUOGU,机器人,2775,vis,maxn,顶点
来源: https://blog.csdn.net/huashuimu2003/article/details/91403460

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有