小Z的推冰块
ice.cpp/in/out
时间限制:1s
题目描述
空间限制:256MB
思路{
首先发现减速带的消除操作是无意义的.因为正权环一定不会最优,
$n,m$有点大,但是$k$比较小,发现一个点停留的位置只有$k$的级别,然后就相当于是跑最短路了.
关键就是把图建出来.
首先把所有特殊点抠出来,再搞两个$set$分别找到上下和左右的第一个特殊点,连边最短路.
自我感觉还算不错的一道$NOIP$题吧~~~~.
}
#include<bits/stdc++.h> #define ll long long #define RG register #define il inline #define N 6000005 #define Mo 6000005 #define int long long using namespace std; int d[N],n,m,hsh[N],k; struct dat1{ int x,y,flag; bool operator <(const dat1 & a)const{ return x==a.x?y<a.y:x<a.x; } }; struct dat2{ int x,y,flag; bool operator <(const dat2 & a)const{ return y==a.y?x<a.x:y<a.y; } }; int pos(int x,int y){ ll Hsh=1ll*(x-1)*m+y; int num=(Hsh%Mo); while(hsh[num]&&hsh[num]!=Hsh)num++; hsh[num]=Hsh; return num; } bool in[N]; set<dat1>s1; set<dat1>::iterator it1; set<dat2>s2; set<dat2>::iterator it2; queue<int>qx,qy; void Modify(int u,int x,int y,int flag){ int v=pos(x,y); if(d[v]>d[u]+1){ d[v]=d[u]+1; if(!in[v])in[v]=1,qx.push(x),qy.push(y); } } void modify(int x,int y){ int u=pos(x,y); it1=s1.upper_bound((dat1){x,y,233}); dat1 temp=*it1;int xx=temp.x,yy=temp.y,F=temp.flag; if(temp.x!=x)xx=x,yy=m,F=-1; if(!F)yy--;Modify(u,xx,yy,F); it1=s1.lower_bound((dat1){x,y,233}); it1--; temp=*it1;xx=temp.x,yy=temp.y,F=temp.flag; if(temp.x!=x)xx=x,yy=1,F=-1; if(!F)yy++;Modify(u,xx,yy,F); it2=s2.upper_bound((dat2){x,y,233}); dat2 tmp=*it2;xx=tmp.x,yy=tmp.y,F=tmp.flag; if(yy!=y)xx=n,yy=y,F=-1; if(!F)xx--;Modify(u,xx,yy,F); it2=s2.lower_bound((dat2){x,y,233}); it2--; tmp=*it2;xx=tmp.x,yy=tmp.y,F=tmp.flag; if(yy!=y)xx=1,yy=y,F=-1; if(!F)xx++;Modify(u,xx,yy,F); } void spfa(){ memset(d,127,sizeof(d)); qx.push(1),qy.push(1); d[pos(1,1)]=0; in[pos(1,1)]=0; while(!qx.empty()){ int x=qx.front(),y=qy.front();qx.pop(),qy.pop(); in[pos(x,y)]=0; modify(x,y); } cout<<d[pos(n,m)]; } main(){ freopen("ice.in","r",stdin); freopen("ice.out","w",stdout); scanf("%lld%lld",&n,&m);int flag;scanf("%lld",&k); for(int i=1;i<=k;++i){ int x,y;scanf("%lld%lld%lld",&x,&y,&flag); s1.insert((dat1){x,y,flag}); s2.insert((dat2){x,y,flag}); } s1.insert((dat1){n,m,233}); s2.insert((dat2){n,m,233}); spfa(); return 0; }