Codeforces Round #355 (Div. 2) D. Vanya and Treasure【分治+BFS】
2016-06-05 16:17
495 查看
大概就是分阶段转移,转移到下一阶段时要考虑一下这阶段点和下一阶段点的乘积,如果小于n*m直接暴力转移,否则的话,一这一阶段的点为起点进行bfs。
/* *********************************************** Author :Maltub Email :xiang578@foxmail.com Blog :htttp://www.xiang578.com ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> //#include <bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<n;i++) #define per(i,a,n) for(int i=n-1;i>=a;i--) #define pb push_back using namespace std; typedef vector<int> VI; typedef long long ll; const int inf=0x3f3f3f3f; const ll mod=1000000007; const int N=300+10; struct node { int x,y; }t,cur; vector<node>v[N*N]; int n,m,p,dp ,a ,vis ,inq ; int dx[]={1,-1,0,0}; int dy[]={0,0,-1,1}; int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d%d",&n,&m,&p)) { for(int i=1;i<=p;i++) v[i].clear(); memset(dp,inf,sizeof(dp)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d",&a[i][j]); t.x=i; t.y=j; v[a[i][j]].push_back(t); if(a[i][j]==1) { dp[i][j]=abs(i-1)+abs(j-1); } } } for(int i=1;i<p;i++) { if(v[i].size()*v[i+1].size()<=n*m) { for(int j=0;j<v[i].size();j++) { int x=v[i][j].x,y=v[i][j].y; for(int k=0;k<v[i+1].size();k++) { int nx=v[i+1][k].x,ny=v[i+1][k].y; dp[nx][ny]=min(dp[nx][ny],dp[x][y]+abs(nx-x)+abs(ny-y)); } } } else { memset(vis,inf,sizeof(vis)); memset(inq,0,sizeof(inq)); queue<node>q; for(int j=0;j<v[i].size();j++) { q.push(v[i][j]); inq[v[i][j].x][v[i][j].y]=1; vis[v[i][j].x][v[i][j].y]=dp[v[i][j].x][v[i][j].y]; } while(!q.empty()) { cur=q.front(); q.pop(); inq[cur.x][cur.y]=0; for(int j=0;j<4;j++) { t.x=cur.x+dx[j]; t.y=cur.y+dy[j]; if(t.x<=0||t.x>n||t.y<=0||t.y>m) continue; //if(a[cur.x][cur.y]+1!=a[t.x][t.y]) continue; int tmp=vis[cur.x][cur.y]+abs(cur.x-t.x)+abs(cur.y-t.y); if(vis[t.x][t.y]>tmp) { vis[t.x][t.y]=tmp; if(inq[t.x][t.y]==0) { inq[t.x][t.y]=1; q.push(t); } } } } for(int j=0;j<v[i+1].size();j++) { dp[v[i+1][j].x][v[i+1][j].y]=vis[v[i+1][j].x][v[i+1][j].y]; } } } printf("%d\n",dp[v[p][0].x][v[p][0].y]); } return 0; }
相关文章推荐
- C++第7次实验(素数和回文)
- JavaAPI之AnnotatedElement接口
- 深入浅出Mybatis系列(十)---SQL执行流程分析(源码篇)
- 期末总结
- UNIX环境高级编程笔记之高级I/O
- mybatis 模糊查询
- C++实验7-最大公约数和最小公倍数
- 关于cell的循环利用
- LocalNote,让你像使用本地文件一样使用印象笔记(支持 markdown 格式)
- poj 3669 bfs+预处理
- 二叉树的非递归建立(一)
- sql 入门经典(第五版) Ryan Stephens 学习笔记 第四部分:建立复杂的数据库查询/
- 第十四周
- C语言宏
- nginx1.81 使用技巧
- 十五周项目1
- C#BitVector32结构操作说明
- 笔记十:复制构造函数、深拷贝、浅拷贝
- 关键路径 SDUTOJ 2498
- 使用 Android Studio自定义View02——图文混排的View