0x26 广搜变形
电路维修 这道题虽然乍一看就会想斜对角的两点之间边权受初始电路的影响要么为0要么为1,但是有一个思考点就是可以通过奇偶性,证明相邻的两个点是不可能在同一个电路中。练习一下双端队列。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[]={-,-,,};
const int dy[]={-,,-,}; char ss[][];
int xx[],yy[],cc[][];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%s",ss[i]+); memset(cc,-,sizeof(cc));
xx[n*m+]=,yy[n*m+]=;cc[][]=;
int head=n*m+,tail=n*m+;bool bk=false;
while(head<=tail)
{
int x=xx[head],y=yy[head];head++;
if(x==n+&&y==m+){printf("%d\n",cc[x][y]);bk=true;break;}
for(int k=;k<=;k++)
{
int tx=x+dx[k],ty=y+dy[k];
if(<tx&&tx<=n+&&<ty&&ty<=m+&&(cc[tx][ty]==-||cc[tx][ty]>cc[x][y]))
{
int g=(!((x>tx)^(y>ty)))?((!(ss[min(x,tx)][min(y,ty)]=='/'))?:):((ss[min(x,tx)][min(y,ty)]=='/')?:);
if(g==)
{
head--;
xx[head]=tx,yy[head]=ty,cc[tx][ty]=cc[x][y];
}
else
{
tail++;
xx[tail]=tx,yy[tail]=ty,cc[tx][ty]=cc[x][y]+;
}
}
}
}
if(bk==false)printf("NO SOLUTION\n");
}
return ;
}
电路维修
poj3635 有点尴尬啊我写的堆优化bfs卡不过去。。。去A*那再做吧
upd:这算哪门子A*啊,真是被discuss的水逼坑死。。。我写了个用路径中最小价格的加油站*油数做预估函数的A*跑的比堆+bfs还慢,结果就是正解就是判断是否之前已经走过更短的(对没错就像最短路那样),剪枝一下就过了???(思维僵化啊菜鸡yzh)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std; int n,m,c[];
struct edge
{
int x,y,d,next;
}a[];int len,last[];
void ins(int x,int y,int d)
{
len++;
a[len].x=x;a[len].y=y;a[len].d=d;
a[len].next=last[x];last[x]=len;
} int C,st,ed;
struct Astar
{
int x,l,s;
friend bool operator>(Astar n1,Astar n2){return n1.s>n2.s;}
};priority_queue<Astar,vector<Astar>,greater<Astar> >q;
int g[][];
void bfs()
{
memset(g,,sizeof(g));g[st][]=;
while(!q.empty())q.pop();
Astar t;
t.x=st, t.l=, t.s=, q.push(t);
while(!q.empty())
{
Astar tno=q.top();q.pop();
if(tno.x==ed)
{
printf("%d\n",tno.s);
return ;
}
if(tno.l+<=C&&g[tno.x][tno.l+]>g[tno.x][tno.l]+c[tno.x])
{
g[tno.x][tno.l+]=g[tno.x][tno.l]+c[tno.x];
t.x=tno.x, t.l=tno.l+, t.s=tno.s+c[t.x], q.push(t);
}
for(int k=last[tno.x];k;k=a[k].next)
{
int y=a[k].y;
if(tno.l>=a[k].d&&g[y][tno.l-a[k].d]>g[tno.x][tno.l])
{
g[y][tno.l-a[k].d]=g[tno.x][tno.l];
t.x=y, t.l=tno.l-a[k].d, t.s=tno.s, q.push(t);
}
}
}
printf("impossible\n");
} int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",&c[i]);
for(int i=;i<=m;i++)
{
int x,y,d;
scanf("%d%d%d",&x,&y,&d);x++,y++;
ins(x,y,d);ins(y,x,d);
}
int Q;
scanf("%d",&Q);
while(Q--)
{
scanf("%d%d%d",&C,&st,&ed);st++,ed++;
bfs();
}
return ;
}
poj3635
hdoj3085 这题真是折腾死了。。。题意有点不清(去找discuss)做法是两个轮流走并且枚举时间层数判断,因为有可能某人(几乎是明明)对于当前时间能够到达的点比另一个多得多。恶心的是这个明明同学一秒三步非常难判,一开始我是写了个三步的方向,结果发现这样会穿墙,然后改成三个走一步套在一起,结果发现拓展的时候,当前秒走了1步和2/3步的拓展是有差异的,但是秒数一样就体现不出来,最后解决的方法就是以1/3秒为单位走,圆满解决
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
const int dx[]={,-,,};
const int dy[]={-,,,}; int n,m,gx1,gy1,gx2,gy2;
char ss[][];
struct node
{
int x,y,c;
}list[][];
int d[][][];
bool check(int x,int y,int asd){return <x&&x<=n&&<y&&y<=m&&d[asd][x][y]==-&&ss[x][y]!='X';}
int getdis(int x,int y){return min(abs(gx1-x)+abs(gy1-y),abs(gx2-x)+abs(gy2-y));}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int T;
scanf("%d",&T);
while(T--)
{
int gx,gy,bx,by,x,y;gx1=-;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s",ss[i]+);
for(int j=;j<=m;j++)
if(ss[i][j]=='M')bx=i,by=j;
else if(ss[i][j]=='G')gx=i,gy=j;
else if(ss[i][j]=='Z')
{
if(gx1==-)gx1=i,gy1=j;
else gx2=i,gy2=j;
}
} int head[],tail[],dep=; bool bk=false;
head[]=, tail[]=, list[][].x=bx, list[][].y=by;
head[]=, tail[]=, list[][].x=gx, list[][].y=gy;
memset(d,-,sizeof(d)); d[][bx][by]=, d[][gx][gy]=;
if(getdis(bx,by)<=||getdis(gx,gy)<=){printf("-1\n");continue;} while(head[]<tail[]&&head[]<tail[])
{
while(d[][list[][head[]].x][list[][head[]].y]==dep)
{
x=list[][head[]].x,y=list[][head[]].y;
if(d[][x][y]!=-&&d[][x][y]!=-)
{
printf("%d\n",max(d[][x][y]%==?d[][x][y]/:d[][x][y]/+,d[][x][y]/));
bk=true;break;
}
if(getdis(x,y)>*(d[][x][y]/+))
{
for(int k=;k<=;k++)
{
int tx=x+dx[k],ty=y+dy[k];
if(check(tx,ty,)&&getdis(tx,ty)>*(d[][x][y]/+))
{
d[][tx][ty]=d[][x][y]+;
list[][tail[]].x=tx, list[][tail[]].y=ty;
tail[]++;
}
}
}
head[]++;
}
if(bk==true)break; while(d[][list[][head[]].x][list[][head[]].y]==dep)
{
x=list[][head[]].x,y=list[][head[]].y;
if(d[][x][y]!=-&&d[][x][y]!=-)
{
printf("%d\n",max(d[][x][y]%==?d[][x][y]/:d[][x][y]/+,d[][x][y]/));
bk=true;break;
}
if(getdis(x,y)>*(d[][x][y]/+))
{
for(int k=;k<=;k++)
{
int tx=x+dx[k],ty=y+dy[k],dis=getdis(tx,ty);
if(check(tx,ty,)&&dis>*((d[][x][y]+)/))
{
d[][tx][ty]=d[][x][y]+;
list[][tail[]].x=tx, list[][tail[]].y=ty;
tail[]++;
}
}
}
head[]++;
}
if(bk==true)break; dep++;
} /* for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%d ",d[0][i][j]==-1?9:d[0][i][j]);
printf("\n");
}
printf("\n");
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%d ",d[1][i][j]==-1?9:d[1][i][j]);
printf("\n");
}*/
if(bk==false)printf("-1\n");
}
return ;
}
hdoj3085
宽搜还是比深搜玩的好一些,但是比较复杂的题细节处理的不好
0x26 广搜变形的更多相关文章
- 电路维修 (广搜变形-双端队列bfs)
# 2632. 「BalticOI 2011 Day1」打开灯泡 Switch the Lamp On [题目描述] 有一种正方形的电路元件,在它的两组相对顶点中,有一组会用导线连接起来,另一组则不会 ...
- HDU--杭电--1195--Open the Lock--深搜--都用双向广搜,弱爆了,看题了没?语文没过关吧?暴力深搜难道我会害羞?
这个题我看了,都是推荐的神马双向广搜,难道这个深搜你们都木有发现?还是特意留个机会给我装逼? Open the Lock Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 5652(二分+广搜)
题目链接:http://acm.hust.edu.cn/vjudge/contest/128683#problem/E 题目大意:给定一只含有0和1的地图,0代表可以走的格子,1代表不能走的格 子.之 ...
- nyoj 613 免费馅饼 广搜
免费馅饼 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy ...
- poj 3984:迷宫问题(广搜,入门题)
迷宫问题 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7635 Accepted: 4474 Description ...
- poj 3278:Catch That Cow(简单一维广搜)
Catch That Cow Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 45648 Accepted: 14310 ...
- 双向广搜 POJ 3126 Prime Path
POJ 3126 Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 16204 Accepted ...
- 广搜+打表 POJ 1426 Find The Multiple
POJ 1426 Find The Multiple Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 25734 Ac ...
- 双向广搜 codevs 3060 抓住那头奶牛
codevs 3060 抓住那头奶牛 USACO 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 农夫约翰被告知一头逃跑奶牛 ...
随机推荐
- Python基本数据类型之字典dict
字典dict 是一个键(key)值(value)对,结构为{},大括号 创建字典 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 info = { # k ...
- B - Even Odds
Problem description Being a nonconformist, Volodya is displeased with the current state of things, p ...
- mvc中Html.AntiForgeryToken的作用和用法
参考:http://blog.csdn.net/cpytiger/article/details/8781457
- WPF 标题栏 右键窗口标题添加关于对话框
/// <summary> /// wpf标题栏 右键菜单 中添加新项 /// </summary> public partial class MainWindow : Win ...
- Google浏览器“无法添加来自此网站的应用、扩展程序和应用脚本”的解决办法
原文链接:https://blog.csdn.net/Fan_Weibin/article/details/80402790 解决方法如下: 在桌面找到Google Chrome图标→右击属性→在快捷 ...
- CSS 弹性盒
图片新窗口打开浏览
- mysql数据库索引原理及其常用引擎对比
索引原理 树数据结构及其算法简介 B+/-树: - 多路搜索树; - 时间复杂度O(logdN);h为节点出度,d为深度 红黑树: - 节点带有颜色的平衡二叉树 - 时间复杂度O(log2N);h节点 ...
- Java中数组的定义方式
数组定义方式一 动态方式(指定数组的长度) 格式: 数组存储的数据类型[]数组名字 = new 数组存储的数据类型[长度]; [] : 表示数组. 数组名字:为定义的数组起个变量名,满足标识符规范,可 ...
- PHP Base64 加密 & 解密
<?php 加密: $cany = 'getshell.top'; #定义要加密的字符串 echo base64_encode($cany); #输出加密后的字符串 解密: $cany = 'Z ...
- 洛谷P3958 奶酪 并查集
两个空洞可互达当且仅当两个空洞相切,即球心距离小于等于球的直径. 一一枚举两个可互达的空洞,并用并查集连起来即可. Code: #include<cstdio> #include<c ...