题目来源:http://codeforces.com/contest/1105/problem/D
题意:编号为1-k的点在一张n*m的表格中依次扩散,每个结点有各自的扩散速度且只可以往上下左右四个方向扩散,表格中每个空白的区域只能被一个结点占领,求最后各个结点所占领的区域的数量。
解题思路:我们可以定义两个队列:que1,que2,que1存放源点的信息,每次取que1中编号相同的结点的信息加入剩余扩散的步数存放入que2中,对que2的结点进行BFS,这样就能保证结点的扩散顺序了。
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<stack> #include<cstdio> #include<map> #include<set> #include<string> #include<queue> using namespace std; #define inf 0x3f3f3f3f typedef long long ll; inline ll gcd(ll i,ll j){ return j==0?i:gcd(j,i%j); } inline ll lcm(ll i,ll j){ return i/gcd(i,j)*j; } const int maxn=1e3+5; int vis[maxn][maxn]; int ans[maxn]; char mp[maxn][maxn]; int v[maxn]; int m,n,p; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; bool jug(int x,int y){ if(x<0||x>=m||y<0||y>=n||vis[x][y]!=0||mp[x][y]!='.') return false; return true; } struct node{ int x,y,id; node(){ x=y=id=0; } node(int x,int y,int id):x(x),y(y),id(id){ } }; struct node1{ int x,y,wi,id; node1(int x,int y,int wi,int id):x(x),y(y),wi(wi),id(id){ } node1(){ x=y=wi=id=0; } }; queue<node> que; void bfs(){ while(!que.empty()){ node tem=que.front(); que.pop(); queue<node1> que1; //cout<<tem.id<<endl; que1.push(node1(tem.x,tem.y,v[tem.id],tem.id)); while(!que.empty()&&que.front().id==tem.id){ que1.push(node1(que.front().x,que.front().y,v[tem.id],tem.id));//找到编号相同的点同时进行扩散 que.pop(); } while(!que1.empty()){ node1 tem1; tem1=que1.front(); que1.pop(); int dx,dy; if(tem1.wi<=0){ que.push(node(tem1.x,tem1.y,tem1.id)); continue; } for(int i=0;i<4;i++){ dx=tem1.x+dir[i][0]; dy=tem1.y+dir[i][1]; if(jug(dx,dy)){ vis[dx][dy]=tem1.id; ans[tem1.id]++; que1.push(node1(dx,dy,tem1.wi-1,tem1.id)); } } } } } int main(){ scanf("%d%d%d",&m,&n,&p); for(int i=1;i<=p;i++){ scanf("%d",&v[i]); } for(int i=0;i<m;i++){ scanf("%s",mp[i]); } for(int i=1;i<=p;i++){ for(int j=0;j<m;j++){ for(int k=0;k<n;k++){ if(mp[j][k]==i+'0'){ vis[j][k]=i; ans[i]++; que.push(node(j,k,i));//保证结点按顺序扩散 } } } } bfs(); /*for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(vis[i][j]==0){ cout<<"#"<<" "; } else cout<<vis[i][j]<<" "; } cout<<endl; }*/ for(int i=1;i<=p;i++){ cout<<ans[i]<<" "; } return 0; }