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
- POJ 3271 Lilypad Pond 最短路径的转化
- poj 3271 Lilypad Pond bfs
- POJ 最短路径
- poj3271 Lilypad Pond bfs
- 变形的最短路径 POJ 3621
- poj 3271 LilyPad
- 路径数限制的最短路径 POJ 3613
- poj 最短路径 汇总
- POJ 3259 最短路径
- poj 1125 最短路径
- 【最短路径】poj 2387
- 【最短路径】poj 1062
- 最短路径__Wormholes( Poj )
- 最短路径__Candies ( Poj )
- poj 2253(最短路径)
- 最短路径-POJ-2387
- bzoj1632 [Usaco2007 Feb]Lilypad Pond
- 1632: [Usaco2007 Feb]Lilypad Pond
- 删边最小生成树
- Spring项目的配置
- 生成随机字符串并排序
- 关于pthread_detach
- 07-图4 哈利·波特的考试 (25分)
- POJ 3271 Lilypad Pond 最短路径的转化
- opwenwrt交叉编译(二)——交叉编译环境的搭建(Ubuntu)
- python网页爬虫代理
- C++多文件结构和编译预处理命令
- WebView注入Java对象注意事项
- 161019
- leetcode 1:Two Sum
- Java final 关键字到底修饰了什么?
- 《Java 源码分析》:Java NIO 之 ServerSocketChannel