您的位置:首页 > 运维架构

bzoj1748 [Usaco2005 open]Around the world 环球飞行

2017-06-07 09:37 495 查看
又见神题= =

这其实是最短路的变形,我们用bfs来跑最短路,然后用map存一下状态,判断有没有重复走。然后最短路的话稍微有一点不一样,从当前点到下一个点有两种路径,如果倒着走就要用现有路径减去,正着走就直接加。

每一次将新的点加入队列答案都加一(显然),当下一个点为1时而且路径不为0(防止你一开始走出去就折返回来),就输出答案。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef pair<int,int> P;
const int N=5e3+5;
const int M=1e5+5;
int go[M],next[M],head[M],n,m;
int a[M];
map<P,int>t;
queue<P> q;
int tot;
inline void add(int x,int y)
{
go[++tot]=y;
next[tot]=head[x];
head[x]=tot;
}
int main()
{
scanf("%d%d",&n,&m);
fo(i,1,n)scanf("%d",&a[i]);
fo(i,1,m)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
q.push(P(1,0));
t[P(1,0)]=1;
while (!q.empty())
{
P x=q.front();
int y=t[x];
q.pop();
for(int i=head[x.first];i;i=next[i])
{
int j=(a[x.first]-a[go[i]]+360)%360;
int k=(a[go[i]]-a[x.first]+360)%360;
P z(go[i],j<k?x.second+j:x.second-k);
if (t[z])continue;
if (go[i]==1&&z.second)
{
printf("%d\n",y);
return 0;
}
q.push(z),t[z]=y+1;
}
}
printf("-1\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: