POJ 3271 Lilypad Pond 最短路径的转化

来源:互联网 发布:程序员教程 第4版 pdf 编辑:程序博客网 时间:2024/06/06 00:36

时空隧道


题意(原谅我懒癌晚期)


分析:
第一次看错题目了…以为是路径总数…直接写spfa…后来发现是0的位置不同才叫方案不同…额…2333333333333
现在考虑我们所求的是0的位置不同的方案总数…
因为1的存在…我们无法直接得到当前路径上0的位置…所以说要想一种机智的办法来排除1的干扰…
第一想法是把1去掉…但是这样会导致一些合法的路径被断开…那怎么办…那就把因为去掉1而断开的边强行加上去一条权值为1的边…
所以我们就可以通过bfs找到每个0点和起点的能够花费1个代价到达的点…从而得到一张新的图,然后再这张图上跑最短路统计方案数即可…
但是在处理方案数目的时候我犯了一个zz的错误…我选择了dijkstra…其实可以统计…但是我妄想用一个”优美“的算法(一遍求出来)…然后就挂了…


代码如下:

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define inf 0x3f3f3f3f//by NeighThornusing namespace std;const int maxn=900+5,maxm=810000+5;int n,m,mp[35][35],hd[maxn],to[maxm],vis[35][35],vi[maxn],nxt[maxm],cnt,stx,sty,enx,eny,mv[8][2]={1,2,-1,2,-1,-2,1,-2,2,1,-2,1,-2,-1,2,-1},dis[maxn];long long num[maxn];struct M{    int v,d;    M(int a=0,int b=0){        v=a,b=d;    }    friend bool operator < (M x,M y){        return x.d>y.d;    }};struct lala{    int x,y,step;    lala(int a=0,int b=0,int c=0){        x=a,y=b,step=c;    }};inline void add(int x,int y){    to[cnt]=y;    nxt[cnt]=hd[x];    hd[x]=cnt++;}inline void bfs(int X,int Y){    memset(vis,0,sizeof(vis));    queue<lala> q;    q.push(lala(X,Y,0)),vis[X][Y]=1;    while(!q.empty()){        int x=q.front().x,y=q.front().y,step=q.front().step;        q.pop();        for(int i=0;i<=7;i++){            int xx=x+mv[i][0],yy=y+mv[i][1];            if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&!vis[xx][yy]&&mp[xx][yy]!=2&&mp[xx][yy]!=3){                if(mp[xx][yy]==4&&step==0)                    add((X-1)*m+Y,(xx-1)*m+yy),vis[xx][yy]=1;                else if(mp[xx][yy]==1&&step==0)                    add((X-1)*m+Y,(xx-1)*m+yy),vis[xx][yy]=1;                else if(mp[xx][yy]==0&&step==0)                    q.push(lala(xx,yy,step)),vis[xx][yy]=1;            }        }    }}inline void findsmallestlength(void){    queue<int> q;memset(dis,inf,sizeof(dis));memset(num,0,sizeof(num));memset(vi,0,sizeof(vi));    q.push((stx-1)*m+sty),vi[(stx-1)*m+sty]=1,dis[(stx-1)*m+sty]=-1,num[(stx-1)*m+sty]=1;    while(!q.empty()){        int top=q.front();q.pop();vi[top]=0;        for(int i=hd[top];i!=-1;i=nxt[i]){            if(dis[to[i]]>dis[top]+1){                dis[to[i]]=dis[top]+1,num[to[i]]=num[top];                if(!vi[to[i]])                    q.push(to[i]),vi[to[i]]=1;            }            else if(dis[to[i]]==dis[top]+1){                num[to[i]]+=num[top];                if(!vi[to[i]])                    q.push(to[i]),vi[to[i]]=1;            }        }    }}signed main(void){    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++){        scanf("%d",&mp[i][j]);        if(mp[i][j]==3)            stx=i,sty=j;        else if(mp[i][j]==4)            enx=i,eny=j;        else if(mp[i][j]!=2)            mp[i][j]^=1;    }cnt=0;    memset(hd,-1,sizeof(hd));    for(int i=1;i<=n;i++)        for(int j=1;j<=m;j++)               if(mp[i][j]==1||mp[i][j]==3)                bfs(i,j);    findsmallestlength();    if(dis[(enx-1)*m+eny]==inf)        puts("-1");    else        cout<<dis[(enx-1)*m+eny]<<endl<<num[(enx-1)*m+eny]<<endl;    return 0;}

by >_< NeighThorn

0 0
原创粉丝点击