蜗牛の狂奔笔记
对于蜗牛来说,狂奔虽不代表极速,但展现的却是一种拼尽全力的姿态........
pku 2908
2009年8月3日
题目链接:
PKU 2908 Quantum
分类:bfs+堆优化
题目分析与算法原型
这道题总的来说是一个广度优先搜索,但是需要用最小堆进行优化(如果不用堆,呵呵,我没试过,不过8成会TLE),每次从队列中取队头元素进行扩展(由于是最小堆,保证了每次取出的元素是当前中花费最小的),需要注意的是,一个已经入过队列的元素,还可以再入队列,只要此时他的花费比上次入队列时小就行,还要注意的一点是结束条件应该是当且队列弹出的队头元素的关键值等于目标关键值,此时可以结束搜索,因为即使以后再次遇到该关键值的元素其花费肯定比现在的大,因为每次从队头开始扩展的元素都会比扩展他的父亲元素的花费大,我就是这个退出条件没搞好结果贡献了n次的WA.............
Code:
1
#include
<
stdio.h
>
2
#include
<
string
.h
>
3
char
beg[
25
],end[
25
];
4
int
n,l,p,w,count,mincost[
1200000
];
5
bool
flag[
1200000
],finish;
6
struct
node
7
{
8
int
cost,num;
9
char
s[
25
];
10
}
queue[
1200000
];
11
struct
caozuo
12
{
13
char
s[
25
];
14
int
cost;
15
}
op[
35
];
16
int
cal(
char
ss[])
17
{
18
int
i,res
=
0
;
19
for
(i
=
0
;i
<
l;i
++
)res
+=
(ss[i]
-
'
0
'
)
<<
(l
-
1
-
i);
20
return
res;
21
}
22
void
down_min_heap(
int
n,
int
h)
//
n表示堆元素的个数,从0开始编号,从h开始往下调整
23
{
24
int
i
=
h,j
=
2
*
i
+
1
;
25
node temp
=
queue[i];
26
while
(j
<
n)
27
{
28
if
(j
<
n
-
1
&&
queue[j].cost
>
queue[j
+
1
].cost)j
++
;
//
若右孩子存在,且右孩子比较小,取右
29
if
(temp.cost
<
queue[j].cost)
break
;
30
else
31
{
32
queue[i]
=
queue[j];
33
i
=
j;
34
j
=
2
*
i
+
1
;
35
}
36
}
37
queue[i]
=
temp;
38
}
39
void
up_min_heap(
int
s)
//
s表示最后一个的编号
40
{
41
while
(s
>
0
&&
queue[s].cost
<
queue[(s
-
1
)
/
2
].cost)
//
从s开始往上调整
42
{
43
node tt
=
queue[s];
44
queue[s]
=
queue[(s
-
1
)
/
2
];
45
queue[(s
-
1
)
/
2
]
=
tt;
46
s
=
(s
-
1
)
/
2
;
47
}
48
}
49
void
push(
int
x,
int
cost,
char
s[])
50
{
51
queue[count].num
=
x;
52
queue[count].cost
=
cost;
53
strcpy(queue[count].s,s);
54
count
++
;
55
up_min_heap(count
-
1
);
56
}
57
node pop()
58
{
59
node res
=
queue[
0
];
60
queue[
0
]
=
queue[count
-
1
];
61
count
--
;
62
down_min_heap(count,
0
);
63
return
res;
64
}
65
void
handle(
int
num,node x,
int
goal,
int
*
ans)
66
{
67
int
i,k;
68
node y
=
x;
69
if
(y.num
==
goal)
70
{
71
finish
=
true
;
72
*
ans
=
y.cost;
73
return
;
74
}
75
for
(i
=
0
;i
<
l;i
++
)
76
{
77
if
(op[num].s[i]
==
'
F
'
)
78
{
79
if
(y.s[i]
==
'
0
'
)y.s[i]
=
'
1
'
;
80
else
y.s[i]
=
'
0
'
;
81
}
82
else
if
(op[num].s[i]
==
'
S
'
)y.s[i]
=
'
1
'
;
83
else
if
(op[num].s[i]
==
'
C
'
)y.s[i]
=
'
0
'
;
84
}
85
k
=
cal(y.s);
86
if
(
!
flag[k]
||
(flag[k]
&&
op[num].cost
+
y.cost
<
mincost[k]))
87
{
88
flag[k]
=
true
;
89
mincost[k]
=
op[num].cost
+
y.cost;
90
push(k,op[num].cost
+
y.cost,y.s);
91
}
92
}
93
int
bfs(
char
a[],
char
b[])
94
{
95
int
r1
=
cal(a),r2
=
cal(b),i,ans;
96
node tt;
97
queue[
0
].num
=
r1;
98
queue[
0
].cost
=
0
;
99
strcpy(queue[
0
].s,a);
100
count
=
1
;
101
flag[r1]
=
true
;
102
mincost[r1]
=
0
;
103
while
(count
>
0
)
104
{
105
tt
=
pop();
106
for
(i
=
0
;i
<
p
&&!
finish;i
++
)handle(i,tt,r2,
&
ans);
107
if
(finish)
return
ans;
108
}
109
return
-
1
;
110
}
111
int
main()
112
{
113
int
i;
114
scanf(
"
%d
"
,
&
n);
115
while
(n
--
)
116
{
117
scanf(
"
%d%d%d
"
,
&
l,
&
p,
&
w);
118
for
(i
=
0
;i
<
p;i
++
)scanf(
"
%s %d
"
,op[i].s,
&
op[i].cost);
119
for
(i
=
0
;i
<
w;i
++
)
120
{
121
scanf(
"
%s %s
"
,beg,end);
122
memset(flag,
false
,
sizeof
(flag));
123
finish
=
false
;
124
int
res
=
bfs(beg,end);
125
if
(res
==-
1
)printf(
"
NP
"
);
126
else
printf(
"
%d
"
,res);
127
if
(i
<
w
-
1
)printf(
"
"
);
128
}
129
printf(
"
\n
"
);
130
}
131
return
1
;
132
}
133
134
135
136
posted on 2009-08-03 10:32
蜗牛也Coding
阅读(175)
评论(0)
编辑
收藏
引用
只有注册用户
登录
后才能发表评论。
【推荐】100%开源!大型工业跨平台软件C++源码提供,建模,组态!
网站导航:
博客园
IT新闻
BlogJava
博问
Chat2DB
管理
Powered by:
C++博客
Copyright © 蜗牛也Coding
<
2009年8月
>
日
一
二
三
四
五
六
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
导航
C++博客
首页
新随笔
联系
聚合
管理
统计
随笔 - 78
文章 - 0
评论 - 96
引用 - 0
常用链接
我的随笔
我的评论
我参与的随笔
留言簿
(8)
给我留言
查看公开留言
查看私人留言
随笔档案
(78)
2011年7月 (1)
2011年4月 (1)
2010年11月 (4)
2010年10月 (4)
2010年9月 (2)
2010年8月 (7)
2010年3月 (1)
2010年2月 (5)
2009年12月 (2)
2009年10月 (1)
2009年9月 (1)
2009年8月 (16)
2009年7月 (31)
2009年6月 (2)
搜索
积分与排名
积分 - 92837
排名 - 258
最新评论
1. re: 关于 OpenGl
太谢谢了。
--袁锋
2. re: 关于 OpenGl
太感谢!
--芙
3. re: 关于MAC系统win 7虚拟机不能上网的问题[未登录]
.vmx文件在哪里?
--a
4. re: MFC中如何将 CFormView放置到一个CDockablePane中
注释掉的创建部分,指针调用
为何不用友元类声明下,就可以用了的。CreateOne,有点绕。
感谢博主分享。
--ren
5. re: 关于 OpenGl
非常感谢~~
--无叶莲
阅读排行榜
1. pragma comment的使用(转)(17219)
2. MFC中如何将 CFormView放置到一个CDockablePane中(8236)
3. (转)关于OpenGL的安装(4832)
4. 关于 OpenGl(4438)
5. VC 界面窗口,静态分割后如何锁定分隔条或限制分隔条的移动范围(4306)
评论排行榜
1. 据说是来自chrome的代码里的一个模板(13)
2. 关于 OpenGl(10)
3. Visual Studio 历史简介(转)(6)
4. pku 1200(6)
5. VC 界面窗口,静态分割后如何锁定分隔条或限制分隔条的移动范围(5)