BZOJ1295: [SCOI2009]最长距离

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1295

windy有一块矩形土地,被分为 N*M 块 1*1 的小格子。 有的格子含有障碍物。 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离。 如果从格子A不可以走到格子B,就没有距离。 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以从X走到Y。 如果windy可以移走T块障碍物,求所有格子间的最大距离。 保证移走T块障碍物以后,至少有一个格子不含有障碍物。

100%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 30 。

题解:初看没有思路,因为不知道取掉哪些障碍物并且距离最大的点对是哪个。

          然后我发现,如果不考虑t的限制,显然把 (1,1)和(n,m)之间的障碍去掉,得到最大距离。

          但如果这之间的障碍数>t,那么我们就考虑下一个距离最远的点,直到它们之间的障碍数<=t,那么输出该点对之间的距离。

          如何计算两点之间的障碍数呢?很简单,最短路,将点权作为权值,求最短路。

          多源最短路?floyed?TLE   NO 我们做n次floyed即可。

代码:

  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 1000
 26 
 27 #define maxm 500+100
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define mod 1000000007
 44 #define num(i,j) ((i-1)*m+j)
 45 #define sqr(x) (x)*(x)
 46 
 47 using namespace std;
 48 
 49 inline int read()
 50 
 51 {
 52 
 53     int x=0,f=1;char ch=getchar();
 54 
 55     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 56 
 57     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 58 
 59     return x*f;
 60 
 61 }
 62 int n,m,t,tot,cnt,d[maxn][maxn],a[maxn],head[maxn];
 63 const int dx[4]={0,0,1,-1};
 64 const int dy[4]={1,-1,0,0};
 65 bool v[maxn];
 66 struct edge{int go,next;}e[4*maxn];
 67 struct rec{double x;int y;}b[maxn*maxn];
 68 priority_queue<pa,vector<pa>,greater<pa> >q;
 69 inline void insert(int x,int y)
 70 {
 71     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;
 72 }
 73 inline void dijkstra(int s)
 74 {
 75     for1(i,n*m)d[s][i]=inf,v[i]=0;
 76     d[s][s]=a[s];
 77     q.push(pa(d[s][s],s));
 78     while(!q.empty())
 79     {
 80         int x=q.top().second;q.pop();if(v[x])continue;v[x]=1;
 81         for(int i=head[x],y;i;i=e[i].next)
 82             if(d[s][x]+a[y=e[i].go]<d[s][y])
 83             {
 84                 d[s][y]=d[s][x]+a[y];
 85                 q.push(pa(d[s][y],y));
 86             }
 87     }
 88 }
 89 inline bool cmp(rec a,rec b){return a.x>b.x;}
 90 
 91 int main()
 92 
 93 {
 94 
 95     freopen("input.txt","r",stdin);
 96 
 97     freopen("output.txt","w",stdout);
 98 
 99     n=read();m=read();t=read();
100     for1(i,n*m)
101     {
102         char ch=' ';
103         while(ch!='0'&&ch!='1')ch=getchar();
104         a[i]=ch-'0';
105     }
106     for1(i,n)
107      for1(j,m)
108       for0(k,3)
109        {
110          int ii=i+dx[k],jj=j+dy[k];
111          if(ii<1||ii>n||jj<1||jj>m)continue;
112          insert(num(i,j),num(ii,jj));
113        }
114     for1(i,n*m)dijkstra(i);
115     for1(i,n)
116      for1(j,m)
117       for1(ii,n)
118         for1(jj,m)
119          b[++cnt].x=sqrt(sqr(i-ii)+sqr(j-jj)),b[cnt].y=d[num(i,j)][num(ii,jj)];
120     sort(b+1,b+cnt+1,cmp);
121     int ans=1;
122     while(b[ans].y>t)ans++;
123     printf("%.6f\n",b[ans].x);
124 
125     return 0;
126 
127 }
View Code

 UPD:看题解发现b数组不用存下来排序,暴力枚举更新答案即可。

代码:

  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 1000
 26 
 27 #define maxm 500+100
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define mod 1000000007
 44 #define num(i,j) ((i-1)*m+j)
 45 #define sqr(x) (x)*(x)
 46 
 47 using namespace std;
 48 
 49 inline int read()
 50 
 51 {
 52 
 53     int x=0,f=1;char ch=getchar();
 54 
 55     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 56 
 57     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 58 
 59     return x*f;
 60 
 61 }
 62 int n,m,t,tot,cnt,d[maxn][maxn],a[maxn],head[maxn];
 63 const int dx[4]={0,0,1,-1};
 64 const int dy[4]={1,-1,0,0};
 65 bool v[maxn];
 66 struct edge{int go,next;}e[4*maxn];
 67 priority_queue<pa,vector<pa>,greater<pa> >q;
 68 inline void insert(int x,int y)
 69 {
 70     e[++tot].go=y;e[tot].next=head[x];head[x]=tot;
 71 }
 72 inline void dijkstra(int s)
 73 {
 74     for1(i,n*m)d[s][i]=inf,v[i]=0;
 75     d[s][s]=a[s];
 76     q.push(pa(d[s][s],s));
 77     while(!q.empty())
 78     {
 79         int x=q.top().second;q.pop();if(v[x])continue;v[x]=1;
 80         for(int i=head[x],y;i;i=e[i].next)
 81             if(d[s][x]+a[y=e[i].go]<d[s][y])
 82             {
 83                 d[s][y]=d[s][x]+a[y];
 84                 q.push(pa(d[s][y],y));
 85             }
 86     }
 87 }
 88 
 89 int main()
 90 
 91 {
 92 
 93     freopen("input.txt","r",stdin);
 94 
 95     freopen("output.txt","w",stdout);
 96 
 97     n=read();m=read();t=read();
 98     for1(i,n*m)
 99     {
100         char ch=' ';
101         while(ch!='0'&&ch!='1')ch=getchar();
102         a[i]=ch-'0';
103     }
104     for1(i,n)
105      for1(j,m)
106       for0(k,3)
107        {
108          int ii=i+dx[k],jj=j+dy[k];
109          if(ii<1||ii>n||jj<1||jj>m)continue;
110          insert(num(i,j),num(ii,jj));
111        }
112     for1(i,n*m)dijkstra(i);
113     double ans=0.0;
114     for1(i,n)
115      for1(j,m)
116       for1(ii,n)
117        for1(jj,m)
118         if(d[num(i,j)][num(ii,jj)]<=t)ans=max(ans,sqrt(sqr(i-ii)+sqr(j-jj)));
119     printf("%.6f\n",ans);
120 
121     return 0;
122 
123 }
View Code

还有此题SPFA貌似更快?不过好像是网格图唉。。。

posted @ 2014-11-11 15:48  ZYF-ZYF  Views(207)  Comments(0Edit  收藏  举报