hdu5094(上海邀请赛E) 状态压缩bfs:取钥匙开门到目的地

网络赛状态压缩与BFS解题技巧

貌似和前段时间的一场网络赛一个类型,状态压缩判断走没走过,然后裸bfs到终点。

其实这类题目很简单就是一个bfs模板,无非就是有一些坑,比如这一题。。一个格子可以有多把钥匙汗==

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 struct dian{
 7     int x,y,state,time;
 8 };
 9 int n,m;
10 int xx[]={1,-1,0,0};
11 int yy[]={0,0,1,-1};
12 int vis[55][55][1100];
13 int g[55][55][55][55],num[55][55],key[55][55][55];
14 int bfs()
15 {
16     queue<dian>q;
17     dian n1,n2;
18     int i,j,temp,x;
19     while (!q.empty()) q.pop();
20     n1.x=1; n1.y=1; n1.time=0; x=0;
21     for (i=1;i<=num[1][1];i++) x=(x|(1<<key[1][1][i]));
22     n1.state=x; q.push(n1); vis[1][1][n1.state]=1;
23     while (!q.empty())
24     {
25         n1=q.front(); q.pop();
26 //        printf("%d %d %d %d\n",n1.x,n1.y,n1.state,n1.time);
27         if (n1.x==n&&n1.y==m) return n1.time;
28         for (i=0;i<4;i++)
29         {
30             n2.x=n1.x+xx[i]; n2.y=n1.y+yy[i];
31             if (n2.x<=0||n2.x>n||n2.y<=0||n2.y>m) continue;
32             if (g[n1.x][n1.y][n2.x][n2.y]!=-1){
33                 temp=(1<<g[n1.x][n1.y][n2.x][n2.y]);
34                 if ((n1.state&temp)==0) continue;
35             }
36             x=n1.state;
37             for (j=1;j<=num[n2.x][n2.y];j++){
38                     temp=(1<<key[n2.x][n2.y][j]);
39                     x=(x|temp);
40             }
41             n2.state=x;
42             if (vis[n2.x][n2.y][n2.state]) continue;
43             vis[n2.x][n2.y][n2.state]=1;
44             n2.time=n1.time+1;
45             q.push(n2);
46         }
47     }
48     return -1;
49 }
50 int main()
51 {
52     int p,k,i,kind,x1,x2,y1,y2,s;
53     while (~scanf("%d%d%d",&n,&m,&p))
54     {
55         memset(g,-1,sizeof(g));
56         memset(num,0,sizeof(num));
57         memset(vis,0,sizeof(vis));
58         scanf("%d",&k);
59         for (i=1;i<=k;i++)
60         {
61             scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&kind);
62             g[x1][y1][x2][y2]=kind;
63             g[x2][y2][x1][y1]=kind;
64         }
65         scanf("%d",&s);
66         for (i=1;i<=s;i++)
67         {
68             scanf("%d%d%d",&x1,&y1,&kind);
69             num[x1][y1]++;
70             key[x1][y1][num[x1][y1]]=kind;
71         }
72         printf("%d\n",bfs());
73     }
74     return 0;
75 }
View Code

http://acm.hdu.edu.cn/showproblem.php?pid=5094

转载于:https://www.cnblogs.com/xiao-xin/articles/4069807.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值