洛谷P1902 刺杀大使(二分答案+bfs验证)
題目描述
伊朗伊斯蘭革命衛隊(某恐怖組織)正在策劃一起刺殺行動,他們的目標是沙特駐美大 使朱拜爾。他們來到了沙特駐美使館,準備完成此次刺殺,要進入使館首先必須通過使館前 的防御迷陣。
迷陣由 n*m 個相同的小房間組成,每個房間與相鄰四個房間之間有門可通行。在第 n 行的 m 個房間里有 m 個機關,這些機關必須全部打開才可以進入大使館。而第 1 行的 m 個 房間有 m 扇向外打開的門,是迷陣的入口。除了第 1 行和第 n 行的房間外,每個房間都被 使館的安保人員安裝了激光殺傷裝置,將會對進入房間的人造成一定的傷害。第 i 行第 j 列 造成的傷害值為 p[i][j](第 1 行和第 n 行的 p 值全部為 0)。
現在伊斯蘭革命衛隊打算以最小傷害代價進入迷陣,打開全部機關,顯然,他們可以選 擇任意多的人從任意的門進入,但必須到達第 n 行的每個房間。一個士兵受到的傷害值為他 到達某個機關的路徑上所有房間的傷害值中的最大值,整個部隊受到的傷害值為所有士兵的 傷害值中的最大值。現在,這個恐怖組織掌握了迷陣的情況,他們需要提前知道怎么安排士 兵的行進路線可以使得整個部隊的傷害值最小。
輸入輸出格式
輸入格式:
第一行有兩個整數 n,m,表示迷陣的大小。
接下來 n 行,每行 m 個數,第 i 行第 j 列的數表示 p[i][j]。
輸出格式:
輸出一個數,表示最小傷害代價。
輸入輸出樣例
輸入樣例#1:
4 2
0 0
3 5
2 4
0 0
輸出樣例#1:
3
說明
50%的數據,n,m<=100;
100%的數據,n,m<=1000,p[i][j]<=1000。
思路:看到最大值最小很容易想到二分答案,然后n<=1000,可以用bfs來驗證。但我一開始從(1,1)開始跑spfa,但不幸只有50,所以遇到二維地圖還是乖乖bfs吧。
題解(二分):
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; int map[1005][1005]; bool vis[1005][1005]; int dx[4]={1,0,-1,0}; int dy[4]={0,1,0,-1}; struct edge{int x,y; }; queue<edge>q; int n,m; bool check(int mid) {memset(vis,0,sizeof(vis));edge s;s.x=1,s.y=1;q.push(s);vis[1][1]=1;while(!q.empty()){edge u=q.front(); q.pop();for(int i=0;i<4;i++){int mx=u.x+dx[i],my=u.y+dy[i];if(mx>=1&&mx<=n&&my>=1&&my<=m&&!vis[mx][my]&&map[mx][my]<=mid){vis[mx][my]=1;q.push((edge){mx,my});}}}bool flag=1;for(int i=1;i<=m;i++){if(!vis[n][i]){flag=0;}}if(!flag){return 0;}else{return 1;} } int main() {scanf("%d%d",&n,&m);int l=0,r=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&map[i][j]);r=max(r,map[i][j]);}}int ans=21474836;while(l<=r){int mid=(l+r)/2;if(check(mid)){r=mid-1;ans=min(ans,mid);}else{l=mid+1;}}printf("%d",ans);return 0; }50分spfa(霧):
#include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<queue> using namespace std; int map[1005][1005]; int dx[4]={1,0,0,-1}; int dy[4]={0,1,-1,0}; int n,m; int dis[1005][1005]; bool vis[1005][1005]; struct cc{int x,y; }; queue<cc>q; void spfa(int s1,int s2) {dis[s1][s2]=map[s1][s2];vis[s1][s2]=1;q.push((cc){s1,s2});while(!q.empty()){cc u=q.front(); q.pop();vis[u.x][u.y]=0;for(int i=0;i<4;i++){int mx=u.x+dx[i],my=u.y+dy[i];if(mx>=1&&mx<=n&&my>=1&&my<=m){if(dis[mx][my]>max(dis[u.x][u.y],map[mx][my])){dis[mx][my]=max(dis[u.x][u.y],map[mx][my]);if(!vis[mx][my]){vis[mx][my]=1;q.push((cc){mx,my});}}}}} } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&map[i][j]);}}int ans=0;memset(dis,63,sizeof(dis));spfa(1,1);for(int i=1;i<=m;i++){ans=max(ans,dis[n][i]);}printf("%d",ans);return 0; }轉載于:https://www.cnblogs.com/-feather/p/7779859.html
總結
以上是生活随笔為你收集整理的洛谷P1902 刺杀大使(二分答案+bfs验证)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GNS3 1.3 10 考CCNA,CC
- 下一篇: 汉诺塔递归问题的分析与Python实现