D.迷宫2 (BFS+优先队列)

https://www.nowcoder.com/acm/contest/69/D

 

即找一条墙壁将起点和终点隔绝,使代价最小。因为可以利用原有墙壁(即原来有墙壁的地方代价为0,还有不能建墙壁的位置代价就为inf)

 

我是从上边和右边开始寻找

 

 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<cstring> 
 5 #include<iostream>
 6 #include<queue>
 7 #include<set>
 8 #include<math.h>
 9 #include<vector> 
10 #include<functional>
11 #include<queue>
12 #define MAXN 1000005 
13 typedef long long ll;
14 using namespace std;
15 const ll inf=1e16;
16 typedef struct Node{
17     ll v;
18     int x,y;
19     bool operator < (const Node &a) const {
20         return v>a.v; //最小值优先
21     }
22     
23 }node;
24 int fx[4][2]={1,0,-1,0,0,1,0,-1};
25 ll map1[502][502],dp[502][502];
26 int main()
27 {    int q,n,m,x;
28     scanf("%d%d%d",&q,&n,&m);
29     while(q--)
30     {
31     for(int i=1;i<=n;i++)
32     for(int j=1;j<=m;j++)
33     {
34         scanf("%d",&x);
35         if(x==0) map1[i][j]=inf;
36         else if(x==-1) map1[i][j]=0;
37         else
38         {
39             map1[i][j]=x;
40         }
41         dp[i][j]=inf;
42     }
43     priority_queue<node> pq;
44     for(int i=1;i<=n;i++)
45         {
46             dp[i][m]=map1[i][m];
47             pq.push((node){dp[i][m],i,m});
48         }
49     for(int i=1;i<m;i++)
50         {
51             dp[1][i]=map1[1][i];
52             pq.push((node){dp[1][i],1,i});
53         }
54     while(!pq.empty())
55     {
56         node t=pq.top();
57         pq.pop();
58         for(int i=0;i<4;i++)
59             {
60                 int ux=t.x+fx[i][0];
61                 int uy=t.y+fx[i][1];
62                 if(ux>=1&&ux<=n&&uy>=1&&uy<=m&&map1[ux][uy]!=-1&&dp[ux][uy]>dp[t.x][t.y]+map1[ux][uy])
63                 {    dp[ux][uy]=dp[t.x][t.y]+map1[ux][uy];
64                     pq.push((node){dp[ux][uy],ux,uy});
65                 }
66             }
67     }
68     ll res=inf;
69     for(int i=1;i<=n;i++)
70         res=min(res,dp[i][1]);
71     for(int i=2;i<=m;i++)
72         res=min(res,dp[n][i]);
73     if(res>=inf) printf("-1\n");
74     else printf("%lld\n",res);
75     }
76     return 0;
77 } 

 

转载于:https://www.cnblogs.com/lnu161403214/p/8511359.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值