P5099 [USACO2004OPEN]Cave Cows 4 洞穴里的牛之四 SPFA
传送门
考虑建图,把x方向z方向距离都不超过2的点连一条边长为1的边,最后跑一遍SPFA。
具体实现可以把点放进一个map里面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
| #include <bits/stdc++.h> #define MAXN 50000 #define pii pair<int,int> inline int read(){ int x=0,f=1; char ch=getchar(); while (ch<'0'||ch>'9'){ if (ch=='-') f=-1; ch=getchar(); } while (ch>='0'&&ch<='9'){ x=(x*10)+(ch-'0'); ch=getchar(); } return x; } using namespace std; vector<int>G[MAXN]; void AddEdge(int u,int v){ G[u].push_back(v); G[v].push_back(u); } map<pii ,int>M; int X[MAXN],Z[MAXN]; int vis[MAXN],dis[MAXN]; int t,n; inline int SPFA(){ queue<int>Q; Q.push(n+1); vis[n+1]=true; for (register int i=1;i<=n;++i){ dis[i]=0x7fffffff; } dis[n+1]=0; while (Q.size()){ int u=Q.front(); Q.pop(); for (register int i=0;i<G[u].size();++i){ int v=G[u][i]; if (!vis[v]){ vis[v]=true; dis[v]=min(dis[v],dis[u]+1); Q.push(v); } } } int ans=0x7fffffff; for (register int i=1;i<=n+1;++i){ if (Z[i]==t){ ans=min(ans,dis[i]); } } if (ans==0x7fffffff){ return -1; } else { return ans; } } int main(){ n=read(),t=read(); for (register int i=1;i<=n;++i){ int x=read(),z=read(); M[make_pair(x,z)]=i; X[i]=x,Z[i]=z; } X[n+1]=Z[n+1]=0; M[make_pair(0,0)]=n+1; for (register int i=1;i<=n+1;++i){ for (register int p=-2;p<=2;++p){ for (register int q=-2;q<=2;++q){ if (p!=0||q!=0){ int ni=X[i]+p,nj=Z[i]+q; if (M.count(make_pair(ni,nj))){ AddEdge(i,M[make_pair(ni,nj)]); } } } } } printf("%d\n",SPFA()); }
|