http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1849
/*思路 : 优先队列 bfs ,从每一天中 病毒类型最小的开始 ,所以优先队列 先 按天 排在按类型 */ #include<iostream> #include<stdio.h> #include<queue> #include<cmath> #include<string.h> #define N 600 using namespace std; struct node { int x; int y; int day; int ty; friend bool operator < (struct node a,struct node b) { if(a.day!=b.day) return a.day>b.day; else return a.ty>b.ty; } }; int map[N][N],d[4][2]={{0,-1},{-1,0},{0,1},{1,0}}; int num[300000],n,m,sum; priority_queue<node>q; node p; void init() { int i,j; while(!q.empty()) q.pop(); sum=0; memset(num,0,sizeof(num)); for(i=0;i<1500;i++) num[i]=0; for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%d",&map[i][j]); if(map[i][j]>0) { p.x=i; p.y=j; p.day=1; p.ty=map[i][j]; num[p.ty]++; sum++; q.push(p); } } } } bool bound(int x,int y) { if(x>=0&&y>=0&&x<n&&y<m) return true; else return false; } void bfs() { node temp; int i; while(!q.empty()) { p=q.top(); q.pop(); int max=-1111111; for(i=0;i<4;i++) { temp.x=p.x+d[i][0]; temp.y=p.y+d[i][1]; temp.day=p.day; temp.ty=p.ty; if(!bound(temp.x,temp.y))continue; if(map[temp.x][temp.y]<0) { if(p.day>=fabs(map[temp.x][temp.y])) { map[temp.x][temp.y]=p.ty; num[p.ty]++; sum++; //printf("%d\n",sum); if(sum==m*n){return ;} q.push(temp); } else { if(map[temp.x][temp.y]>max)//寻找周为最容易感染的 max=map[temp.x][temp.y]; } } } if(max!=-1111111) { p.day=-max; //若不能感染周围的 ,则等下一天 q.push(p); } } } int main() { int t,b; while(cin>>n>>m) { init(); bfs(); cin>>t; while(t--) { scanf("%d",&b); printf("%d\n",num[b]); } } }