zoukankan      html  css  js  c++  java
  • BZOJ1698: [Usaco2007 Feb]Lilypad Pond 荷叶池塘

    一傻逼题调了两天。。

    n<=30 * m<=30的地图,0表示可以放平台,1表示本来有平台,2表示不能走,3起点4终点,走路方式为象棋的日字,求:从起点走到终点,至少要放多少平台,以及放平台的方案数,无解-1。

    方法一:其实能走直接平台的就可以直接走来走去,也就是算一个联通块。类似于tarjan,先把一大块缩成一点,然后连边走最短路。

    错误!存在边权为0的边,会导致统计方案出现重复。比如:

    圆圈走到三角形,直接走和绕一圈是一样的,但算了两次。

    方法二:把0边去掉就行了。由于数据小,开个数组[a][b][c][d]表示a,b到c,d是否能通过填一块到达,这个数组只需对每个点做一次搜索就能出来。最后就是最短路啦。

    不过边权为1,谁最短路会写迪杰呢?肯定bfs啦!

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<algorithm>
      5 //#include<iostream>
      6 using namespace std;
      7 
      8 int n,m;
      9 int a[33][33],can[33][33][33][33];
     10 #define maxn 1011
     11 #define maxm 10011
     12 struct Edge{int tx,ty,next;}edge[maxn*maxn];int first[33][33],le=2;
     13 #define LL long long
     14 void in(int sx,int sy,int tx,int ty)
     15 {
     16     Edge &e=edge[le];
     17     e.tx=tx;e.ty=ty;
     18     e.next=first[sx][sy];
     19     first[sx][sy]=le++;
     20 }
     21 int nx,ny;
     22 const int dx[]={1,1,2,2,-1,-1,-2,-2},dy[]={2,-2,1,-1,2,-2,1,-1};
     23 bool vis[33][33];
     24 void dfs(int x,int y)
     25 {
     26     vis[x][y]=1;
     27     for (int i=0;i<8;i++)
     28     {
     29         const int xx=x+dx[i],yy=y+dy[i];
     30         if (xx<1 || xx>n || yy<1 || yy>m || can[nx][ny][xx][yy]
     31         || a[xx][yy]==2 || vis[xx][yy]) continue;
     32         if (a[xx][yy]==0 || a[xx][yy]==4)
     33         {
     34             can[nx][ny][xx][yy]=1;
     35             continue;
     36         }
     37         dfs(xx,yy);
     38     }
     39 }
     40 const int inf=0x3f3f3f3f;
     41 int dis[33][33];LL way[33][33];
     42 struct qnode{int x,y;}q[maxn];int head,tail;
     43 void bfs(int sx,int sy)
     44 {
     45     head=0;tail=1;q[0].x=sx;q[0].y=sy;
     46     for (int i=1;i<=n;i++)
     47         for (int j=1;j<=m;j++)
     48             dis[i][j]=inf;
     49     dis[sx][sy]=0;way[sx][sy]=1;
     50     while (head!=tail)
     51     {
     52         const int nx=q[head].x,ny=q[head++].y;
     53         for (int i=first[nx][ny];i;i=edge[i].next)
     54         {
     55             const Edge &e=edge[i];
     56             if (dis[e.tx][e.ty]>dis[nx][ny]+1)
     57             {
     58                 dis[e.tx][e.ty]=dis[nx][ny]+1;
     59                 way[e.tx][e.ty]=way[nx][ny];
     60                 q[tail].x=e.tx,q[tail++].y=e.ty;
     61             }
     62             else if (dis[e.tx][e.ty]==dis[nx][ny]+1)
     63                 way[e.tx][e.ty]+=way[nx][ny];
     64         }
     65     }
     66 }
     67 int main()
     68 {
     69     scanf("%d%d",&n,&m);
     70     int sx,sy,tx,ty;
     71     for (int i=1;i<=n;i++)
     72         for (int j=1;j<=m;j++)
     73         {
     74             scanf("%d",&a[i][j]);
     75             if (a[i][j]==3) sx=i,sy=j;
     76             if (a[i][j]==4) tx=i,ty=j;
     77         }
     78     for (int i=1;i<=n;i++)
     79         for (int j=1;j<=m;j++)
     80         {
     81             memset(can[i][j],0,sizeof(can[i][j]));
     82             memset(vis,0,sizeof(vis));
     83             if (a[i][j]==2) continue;
     84             nx=i;ny=j;
     85             dfs(i,j);
     86         }
     87     memset(first,0,sizeof(first));
     88     for (int i=1;i<=n;i++)
     89         for (int j=1;j<=m;j++)
     90             for (int k=1;k<=n;k++)
     91                 for (int l=1;l<=m;l++)
     92                 {
     93                     if (can[i][j][k][l]) 
     94                     {
     95                         in(i,j,k,l);
     96                     }
     97                 }
     98     bfs(sx,sy);
     99     if (dis[tx][ty]==inf) puts("-1");
    100     else printf("%d
    %lld
    ",dis[tx][ty]-1,way[tx][ty]);
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    【Thymeleaf】遇到Current request is not a multipart request不要慌,检查页面中form的属性enctype="multipart/formdata"是否正确就对了
    [CSS]让ul中的li在所属div内成一行居中显示。
    【JS】将yyyyMMdd hh:mm:ss的字符串时间转换为JS时间
    分页资料收集
    【oralce/springboot/jquery】自行实现分页
    【JS】一小时之内显示红饼图标,两小时之内选择黄星图标,否则显示时间
    【JavaScript】给动态生成的链接动态的绑定事件
    VBA在Excel中的应用(四)
    在MOSS 2007中自定义DataView Webpart的数据显示样式
    ASP.NET中的缩略图应用
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7567963.html
Copyright © 2011-2022 走看看