codevs1024一塔湖图(丧心病狂的建图)

/*
丧心病狂的最短路 关键是建图
根据题目中给的路 拆出节点来 建图  (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;
}

 

posted @ 2016-04-19 11:00  一入OI深似海  阅读(299)  评论(0编辑  收藏  举报