4/6 深搜广搜专题+二分答案+单调队列
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4/6 深搜广搜专题+二分答案+单调队列相关的知识,希望对你有一定的参考价值。
经典迷宫问题:
P6207 [USACO06OCT] Cows on Skates G
1.广搜可用于查找最少需要的步数,而深搜可求出到达终点的路经数。
2.可开一个数组记录路径,最后用深搜回溯路径。注意起点和终点的设置,可能需要自行补上。
#include<bits/stdc++.h>
#define int long long
using namespace std;
int r,c,way[155][155][2];
int dx[4]=-1,1,0,0;
int dy[4]=0,0,1,-1;
char mp[155][155];
bool vis[155][155];
struct node
int x,y,s;
;
queue<node>q;
void dfs(int xx,int yy)
if(!way[xx][yy][0]&&!way[xx][yy][1]) return;
dfs(way[xx][yy][0],way[xx][yy][1]);
cout<<way[xx][yy][0]<<" "<<way[xx][yy][1]<<endl;
signed main()
cin>>r>>c;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
cin>>mp[i][j];
vis[1][1]=1;
q.push(node1,1,0);
while(!q.empty())
node cur=q.front();q.pop();
int x=cur.x,y=cur.y;
if(x==r&&y==c)
break;
for(int i=0;i<4;i++)
int nx=x+dx[i],ny=y+dy[i];
if(nx<=0||nx>r||ny<=0||ny>c) continue;
if(!vis[nx][ny]&&mp[nx][ny]=='.')
vis[nx][ny]=1;
way[nx][ny][0]=x;way[nx][ny][1]=y;
q.push(nodenx,ny,cur.s+1);
dfs(r,c);
cout<<r<<" "<<c<<endl;
return 0;
2.动态迷宫问题
P3395 路障
在每秒结束后放上一个路障。
关键关键:::注意yes和no输出的格式,看错了即使全敲对了也零分。
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2005;
int n,zx[N],zy[N];
int dx[4]=-1,1,0,0;
int dy[4]=0,0,1,-1;
int mp[N][N];
bool vis[N][N];
struct node
int x,y,s;
;
queue<node>q;
signed main()
int t;cin>>t;
while(t--)
while(!q.empty()) q.pop();
memset(mp,0,sizeof(mp));
memset(vis,0,sizeof(vis));
int n;cin>>n;
for(int i=1;i<=2*n-2;i++)
cin>>zx[i]>>zy[i];
vis[1][1]=1;
q.push(node1,1,0);
int flag=0;
while(!q.empty())
node cur=q.front();q.pop();
int x=cur.x,y=cur.y,g=cur.s;
if(x==n&&y==n)
flag=1;break;
mp[zx[g]][zy[g]]=1;
for(int i=0;i<4;i++)
int nx=x+dx[i],ny=y+dy[i];
if(nx<=0||nx>n||ny<=0||ny>n)
continue;
if(!vis[nx][ny]&&!mp[nx][ny])
vis[nx][ny]=1;q.push(nodenx,ny,g+1);
if(flag)
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
return 0;
广搜的灵活应用:
P3906 Geodetic集合
1.先利用广搜对于每个点进行松弛操作,记录到达这个点最短路径的前驱点。
2.根据终点,和记录的前驱点,遍历回起点,记录遍历过的点,方便输出。
#include<bits/stdc++.h>
#define long long ll
using namespace std;
const int inf=0x3f3f3f3f;
const int N=105;
int n,m,k,g[N][N],dist[N],pre[N][N],num[N];
bool vis[N];
void bfs(int u,int v)
memset(num,0,sizeof(num));
memset(dist,inf,sizeof(dist));
memset(vis,0,sizeof(vis));
queue<int>q;dist[u]=0;
q.push(u);
while(!q.empty())
int s=q.front();q.pop();
if(vis[s]) continue;
vis[s]=1;
for(int i=1;i<=n;i++)
if(g[s][i])
if(dist[i]>dist[s]+1)
dist[i]=dist[s]+1;
pre[i][++num[i]]=s;
q.push(i);
else if(dist[i]==dist[s]+1)
pre[i][++num[i]]=s;
memset(vis,0,sizeof(vis));
q.push(v);vis[v]=1;
while(!q.empty())
int s=q.front();q.pop();
for(int i=num[s];i>=1;i--)
if(!vis[pre[s][i]])
vis[pre[s][i]]=1;
q.push(pre[s][i]);
for(int i=1;i<=n;i++)
if(vis[i])
cout<<i<<" ";
cout<<endl;
signed main()
cin>>n>>m;
for(int i=1;i<=m;i++)
int u,v;cin>>u>>v;
g[u][v]=g[v][u]=1;
cin>>k;
while(k--)
int u,v;cin>>u>>v;
bfs(u,v);
return 0;
深搜经典题目:
P2196 [NOIP1996 提高组] 挖地雷
#include<bits/stdc++.h>
#define long long ll
using namespace std;
const int inf=0x3f3f3f3f;
const int N=55;
int n,a[N],g[N][N],path[N],ans[N],mx,gg;
bool vis[N];
bool check(int u)
for(int i=1;i<=n;i++)
if(g[u][i]&&!vis[i])
return 1;
return 0;
void dfs(int id,int step,int sum)
if(!check(id))
if(mx<sum)
mx=sum;gg=step;
for(int i=1;i<=step;i++) ans[i]=path[i];
for(int i=1;i<=n;i++)
if(g[id][i]&&!vis[i])
path[step+1]=i;
vis[i]=1;
dfs(i,step+1,sum+a[i]);
vis[i]=0;
signed main()
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
int x;cin>>x;
if(x)
g[i][j]=1;
for(int i=1;i<=n;i++)
path[1]=i;
vis[i]=1;
dfs(i,1,a[i]);
vis[i]=0;
for(int i=1;i<=gg;i++)
cout<<ans[i]<<" ";
cout<<endl;
cout<<mx<<endl;
return 0;
P2920 [USACO08NOV]Time Management S
二分枚举起点。注意特判-1的情况!!
#include<bits/stdc++.h>
#define long long ll
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1005;
int n,ans,mx=inf;
struct work
int st,ti,ed;
e[N];
bool cmp(work e1,work e2)
return e1.ed<e2.ed;
bool check(int x)
for(int i=1;i<=n;i++)
x+=e[i].ti;
if(x>e[i].ed)
return 0;
return 1;
signed main()
cin>>n;
for(int i=1;i<=n;i++)
cin>>e[i].ti>>e[i].ed;
e[i].st=e[i].ed-e[i].ti;
mx=min(mx,e[i].st);
sort(e+1,e+n+1,cmp);
int l=0,r=mx;
while(l<=r)
int mid=(以上是关于4/6 深搜广搜专题+二分答案+单调队列的主要内容,如果未能解决你的问题,请参考以下文章