【20190619】flower

一道关于优先队列的搜索题。

我们建立一个小根堆,将开始确定的值放进去,然后进行bfs。

对于每个点,向上下左右四个方向扩展,并且更新答案,同时将没入队的节点入队即可。

最后,我们得到了一个搜索完成的图,我们判断一下合法性,输出答案即可。

这道题有一个坑点:输入可能重复同一节点但权值不同,这种情况应当判错。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7 typedef long long ll;
 8 int n,m;
 9 ll map[1010][1010];
10 int num,d;
11 const int mod=1000000007;
12 int dx[5]={0,0,0,1,-1};
13 int dy[5]={0,1,-1,0,0};
14 inline int read() {
15     int ret=0;
16     int op=1;
17     char c=getchar();
18     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
19     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
20     return ret*op;
21 }
22 struct node {
23     int x,y,val;
24     bool operator <(const node &x) const {
25         return val>x.val;
26     }
27 };
28 priority_queue<node> q;
29 int vis[1010][1010];
30 int main() {
31     freopen("flower.in","r",stdin);
32     freopen("flower.out","w",stdout);
33     n=read(); m=read();
34     num=read(); d=read();
35     for(int i=1;i<=n;i++)
36         for(int j=1;j<=m;j++)
37             map[i][j]=2147483646;
38     for(int i=1;i<=num;i++) {
39         int x=read(),y=read(),z=read();
40         if(map[x][y]!=2147483646&&map[x][y]!=z) {
41             puts("Boom");
42             return 0;
43         }
44         map[x][y]=z;
45         q.push((node){x,y,z});
46         vis[x][y]=1;
47     }
48     while(!q.empty()) {
49         int nowx=q.top().x;
50         int nowy=q.top().y;
51         q.pop();
52         for(int k=1;k<=4;k++) {
53             int xx=nowx+dx[k];
54             int yy=nowy+dy[k];
55             if(xx<1||xx>n||yy<1||yy>m||vis[xx][yy]) continue ;
56             map[xx][yy]=min(map[xx][yy],map[nowx][nowy]+d);
57             q.push((node){xx,yy,map[xx][yy]});
58             vis[xx][yy]=1;
59         }
60     }
61     ll ans=0;
62     for(int i=1;i<=n;i++)
63         for(int j=1;j<=m;j++)
64             ans=(ans+map[i][j])%mod;
65     for(int i=1;i<=n;i++)
66         for(int j=1;j<=m;j++) {
67             for(int k=1;k<=4;k++) {
68                 int ii=i+dx[k];
69                 int jj=j+dy[k];
70                 if(ii>=1&&ii<=n&&jj<=m&&jj>=1&&map[i][j]+d<map[ii][jj]) {
71                     puts("Boom");
72                     return 0;
73                 }
74                 if(ii>=1&&ii<=n&&jj<=m&&jj>=1&&map[i][j]-d>map[ii][jj]) {
75                     puts("Boom");
76                     return 0;
77                 }
78             }
79         }
80     printf("%lld",ans%mod);
81     return 0;
82 }
AC Code

猜你喜欢

转载自www.cnblogs.com/shl-blog/p/11051681.html