题目链接:点击打开链接
题意:给定n*m的矩阵
有一个人a从左上角↖走到右下角↘,只能↓或→走
另一个人b从左下角↙走到右上角↗,只能↑或→走
使得2个人的路径有且仅有一个格子是相交的。
统计2个人的权值和(相交格子的权值和不计)
问最大的权值和是多少。
思路:
首先转换一下题意,也就是找一个格子与4个角落连不相交的线。
我们观察相交的那个格子,那个格子的上下左右必然对应着一个角落。
(i,j)点,那么(i-1,j)必然对应左上角或右上角的其中一个角落。
这样(i,j)点的4个相邻格子各自对应一个角落(这种情况有2种)
剩下任务就是计算每个格子到某个角落的最大权值和。
bfs以4个角落为起点,预处理出任意点到该角落的最大路径和。
然后枚举一下相交点。
#include<stdio.h> #include<string.h> #include<vector> #include<algorithm> #include<iostream> #include<queue> using namespace std; #define N 1005 #define ll __int64 ll vis[N][N], Time; ll n, m; ll dis[4][N][N]; int aaaa; int cccc; ll mp[N][N]; ll step[4][2][2] = { {0,1,1,0}, {0,-1,1,0}, {-1,0,0,1}, {-1,0,0,-1}}; void bfs(ll cur, ll x, ll y){ vis[x][y] = Time; queue<ll>qx,qy; qx.push(x); qy.push(y); dis[cur][x][y] = mp[x][y]; while(!qx.empty()){ x = qx.front(); qx.pop(); y = qy.front(); qy.pop(); for(ll i = 0; i < 2; i++){ ll nowx = x + step[cur][i][0], nowy = y + step[cur][i][1]; if(!(1<=nowx&&nowx<=n&&1<=nowy&&nowy<=m))continue; dis[cur][nowx][nowy] = max(dis[cur][nowx][nowy], mp[nowx][nowy]+dis[cur][x][y]); if(vis[nowx][nowy]==Time)continue; vis[nowx][nowy] = Time; qx.push(nowx); qy.push(nowy); } } } int main(){ ll u, v, i, j, que; Time = 0; while(~scanf("%I64d %I64d",&n,&m)){ memset(dis, 0, sizeof dis); for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%I64d",&mp[i][j]); Time++; bfs(0,1,1); Time++; bfs(1,1,m); Time++; bfs(2,n,1); Time++; bfs(3,n,m); ll ans = 0; for(i=2;i<n;i++) for(j=2;j<m;j++) { ll tmp = dis[0][i-1][j] + dis[1][i][j+1] + dis[2][i][j-1] + dis[3][i+1][j]; ans = max(ans, tmp); tmp = dis[0][i][j-1] + dis[1][i-1][j] + dis[2][i+1][j] + dis[3][i][j+1]; ans = max(ans, tmp); } printf("%I64d\n",ans); } return 0; } /* 3 4 100 100 100 100 100 1 100 100 100 100 100 100 4 4 10 10 10 10 100 100 100 100 100 1 100 100 100 100 100 100 3 4 10 10 10 10 100 1 100 100 100 100 100 100 */
Codeforces 429B Working out bfs构造,布布扣,bubuko.com
Codeforces 429B Working out bfs构造
原文地址:http://blog.csdn.net/acmmmm/article/details/25625151