/* 丧心病狂的最短路 关键是建图 根据题目中给的路 拆出节点来 建图 (i,j) -->(j-1)*n+i 然后根据障碍 把死路 湖覆盖的dis改变成极大值 然后Floyd 然后 然后就没有然后了.... */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 99999999; using namespace std; int g[150][150],x[11],y[11],s,n,m,t,k; void Input() { cin>>n>>m>>t>>k; s=n*m;//图中节点个数 int i,j; for(i=1;i<=n;i++) cin>>x[i]; for(i=1;i<=m;i++) cin>>y[i]; } void Build() { int i,j; memset(g,127/3,sizeof(g));//初始化 for(i=1;i<=s;i++) g[i][i]=0; for(i=1;i<=n;i++)//先按给出的路建一遍 for(j=1;j<=m;j++)//以(i,j)为基点 四个方向建图 { if(i>1)g[(j-1)*n+i][(j-1)*n+i-1]=x[i]-x[i-1];//向左 if(j>1)g[(j-1)*n+i][(j-1-1)*n+i]=y[j]-y[j-1];//向上 if(i<n)g[(j-1)*n+i][(j-1)*n+i+1]=x[i+1]-x[i];//向右 if(j<m)g[(j-1)*n+i][(j-1+1)*n+i]=y[j+1]-y[j];//向下 } int x1,y1,x2,y2; for(i=1;i<=t;i++)//处理路 (有点问题好像 不能覆盖每条路里面的点- -) { cin>>x1>>y1>>x2>>y2; g[(y1-1)*n+x1][(y2-1)*n+x2]=maxn; g[(y2-1)*n+x2][(y1-1)*n+x1]=maxn; } for(int l=1;l<=k;l++)//处理湖 注意:边界可以走 { cin>>x1>>x2>>y1>>y2; for(i=x1;i<=x2-1;i++)//处理x方向的 只向右延伸 for(j=y1+1;j<=y2-1;j++) { g[(j-1)*n+i][(j-1)*n+i+1]=maxn; g[(j-1)*n+i+1][(j-1)*n+i]=maxn; } for(j=y1;j<=y2-1;j++)//处理y方向的 只向下延伸 for(i=x1+1;i<=x2-1;i++) { g[(j-1)*n+i][(j-1+1)*n+i]=maxn; g[(j-1+1)*n+i][(j-1)*n+i]=maxn; } } } void Floyd() { int i,j,k; for(k=1;k<=s;k++) for(i=1;i<=s;i++) for(j=1;j<=s;j++) if(g[i][j]>g[i][k]+g[k][j]) g[i][j]=g[i][k]+g[k][j]; } void Printf() { int x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2; cout<<g[(y1-1)*n+x1][(y2-1)*n+x2]; } int main() { Input(); Build(); Floyd(); Printf(); return 0; }
时间: 2024-10-09 09:57:33