ZOJ 1430 / POJ 2679 The Erythea Campaign (bfs+dijkstra)
2010-08-28 00:07
549 查看
繁,但是不难。
首先,建图,题中给出的是m*n的矩阵,里面包含了所有stronghold的分布,但是你需要把他转换成一个图。但是路径不能穿过堡垒,多以说两个堡垒之间的两个点不能相互到达。还有就是每个点应该保存它可以到达的点的信息,当使用dijkstra求最短路径的时候,这些点可以当邻接表使用,很方便的。
接下来是每个的危险值,求法是m+n-d,不会出现负值。d的意思是它到达离他最近的堡垒的距离。对于每个堡垒上的点做bfs求出所有点到他的最短距离,如果求出的距离比之前更新的距离小的话,就存那个小的。
首先,建图,题中给出的是m*n的矩阵,里面包含了所有stronghold的分布,但是你需要把他转换成一个图。但是路径不能穿过堡垒,多以说两个堡垒之间的两个点不能相互到达。还有就是每个点应该保存它可以到达的点的信息,当使用dijkstra求最短路径的时候,这些点可以当邻接表使用,很方便的。
接下来是每个的危险值,求法是m+n-d,不会出现负值。d的意思是它到达离他最近的堡垒的距离。对于每个堡垒上的点做bfs求出所有点到他的最短距离,如果求出的距离比之前更新的距离小的话,就存那个小的。
#include<iostream> #include<cstring> #include<queue> const int INF = 99999999; const int MAXLIST = 7000; const int MAXMAP = 82; using namespace std; struct node { int value; //危险值 bool isedge; //是否是边界点 int order; //点的序号 int reach[4]; //可以到达的点的序号 } map[MAXMAP][MAXMAP],list[MAXLIST];//list是类似于临接表的东西 int m,n;//n行,m列 char c; int cases; int startx,starty,endx,endy; //开始和结束的坐标 int start,end; //开始和结束的点在list里面的位置 int stronghold[MAXMAP][MAXMAP]; // 堡垒的分布 int flag[MAXLIST],dist[MAXLIST]; //dijkstra时候用的 void bfs(int n) //求出到所有点到n的距离 { queue<int> q; int inq[MAXLIST],t,dist; for(int i= 0;i <MAXLIST;i++) inq[i] = 0; inq = 1;q.push(n);list .value=0; while( !q.empty() ) { n = q.front();q.pop(); dist = list .value+1; for(int j=0; j < 4; j++) { t = list .reach[j]; if( t==0 ) continue; if( list[t].value > dist ) { list[t].value = dist; q.push(t);inq[t] = 1;} } } } void dijkstra(int a) { int now,min,v = (n+1)*(m+1); for(int i=1;i <= v;i++) {dist[i]=INF;flag[i]=0;} dist[now=a] = list[a].value;flag[a] = 1; for(int i = 1; i < v; i++) { for(int j = 0; j < 4; j++) { int to = list[now].reach[j]; if(to == 0) continue; if( dist[to] > dist[now] + list[to].value ) dist[to] = dist[now] + list[to].value; } min = INF; for(int j = 1; j <= v; j++) if( !flag[j] && dist[j] < min ) min = dist[now=j]; flag[now] = 1; } } int main(void) { cin >> cases; while( cases-- ) { cin >> n >> m; cin >> startx >> starty >> endx >> endy; starty++;endy++; start = (m+1)*startx + starty; end = (m+1)*endx + endy; memset(stronghold,0,sizeof(stronghold)); for( int i = 0; i < n; i++ ) //输入stronghold { getchar(); for( int j = 0; j < m; j++ ) stronghold[i][j] = (c=getchar()) - '0'; } for( int i = 0,order = 1; i <= n; i++ ) //将图中的order和isedge初始化 for( int j = 0; j <= m; j++ ) { map[i][j].order = order++; map[i][j].isedge = false; } for( int i = 0; i < n; i++ ) //判断某个点是不是堡垒的边界点 for( int j = 0; j < m; j++ ) if( stronghold[i][j] == 1 ) map[i][j].isedge = map[i+1][j].isedge = map[i][j+1].isedge = map[i+1][j+1].isedge = 1; for( int i = 0; i <= n; i++ ) //点map【i】【j】可以到达的点在list中的位置 for( int j = 0; j <= m; j++ ) //不可以到的为零 { map[i][j].reach[0] = i>0?map[i-1][j].order:0; map[i][j].reach[1] = j>0?map[i][j-1].order:0; map[i][j].reach[2] = i<n?map[i+1][j].order:0; map[i][j].reach[3] = j<m?map[i][j+1].order:0; } for( int i = 0; i < n; i++ ) //两个堡垒相邻的话他们中间那个路不能走 for( int j = 0; j < m; j++ ) { if( stronghold[i][j] == 1 && stronghold[i][j+1] == 1 ) map[i][j+1].reach[2] = map[i+1][j+1].reach[0] = 0; if( stronghold[i][j] == 1 && stronghold[i+1][j] == 1 ) map[i+1][j].reach[3] = map[i+1][j+1].reach[1] = 0; } for( int i = 0,order = 1; i <= n; i++ ) //把map中的东西转移到list中 for( int j = 0; j <= m; j++ ) { map[i][j].value = INF; list[order++] = map[i][j]; } for( int i = 0; i <= n; i++ ) // 每个点的到所有堡垒边界点的最短距离 for( int j= 0; j <= m; j++ ) if( map[i][j].isedge ) bfs(map[i][j].order); for(int i = 1;i <= (n+1)*(m+1); i++ ) list[i].value = m+n-list[i].value; //危险值 dijkstra(start); if (dist[end] == INF ) cout << "no solution/n"; else cout << dist[end] <<endl; } return 0; }
相关文章推荐
- ZOJ 1430 The Erythea Campaign(最短路)
- ZOJ1430 POJ1697 The Erythea Campaign
- zoj 1430 || poj 1697 The Erythea Campaign
- ZOJ Walk Through the Forest (dijkstra + BFS || 记忆化搜索)
- ZOJ 2416 Open the Lock (BFS)
- ZOJ 3781 - Paint the Grid Reloaded(缩点dfs+bfs)
- ZOJ 3675 Trim the Nails(bfs+位运算处理)
- ZOJ 3781 Paint the Grid Reloaded(BFS)
- bfs ZOJ 2416 Open the Lock
- ZOJ 2864 Catch the thief(多条最短路+BFS)
- zoj 1530 Find The Multiple(bfs)
- ZOJ 3781 Paint the Grid Reloaded ( BFS(重点是对问题的分析) )
- ZOJ 3675 Trim the Nails(bfs)
- 计蒜客 Emptying the Baltic (BFS+Dijkstra)
- zoj 3781 Paint the Grid Reloaded (bfs)
- ZOJ 3781 Paint the Grid Reloaded 图论 bfs
- ZOJ 3675 Trim the Nails (状态压缩+BFS)
- ZOJ 3781 Paint the Grid Reloaded 缩点+bfs
- UVALive2701 UVA1189 POJ1426 ZOJ1530 Find The Multiple【BFS】
- ZOJ 3781 Paint the Grid Reloaded 题解 (dfs缩点+BFS)