codeforces 1105 d 多源点bfs..
题目:https://codeforces.com/contest/1105/problem/D
题意:给定n个点人,拥有不同数量且不同位置的点,让它们按不同的速度进行扩散..(同等时间的时候,人开始是1..n)
做法:多源点bfs..处理的时候两个vector来回倒腾..break条件要处理好。。
下面是别人代码:懒得自己打了。。
#include<bits/stdc++.h> using namespace std; #define mp make_pair #define pb push_back vector<pair<int,int> > v[10],t; int n,m,p,s[10],a[1011][1101],ans[10],tn,d[4][2]; char str[1101]; bool bfs(int x) { t.clear(),tn=v[x].size(); for (int i=0; i<tn; i++) t.pb(v[x][i]); v[x].clear(); for (int i=0; i<tn; i++) { int X=t[i].first,Y=t[i].second; for (int j=0; j<4; j++) if (a[X+d[j][0]][Y+d[j][1]]==0) a[X+d[j][0]][Y+d[j][1]]=x,v[x].pb(mp(X+d[j][0],Y+d[j][1])); } if (!v[x].size()) return 0; return 1; } int main(){ for (int i=0; i<=1001; i++) for (int j=0; j<=1001; j++) a[i][j]=-1; d[0][0]=d[1][0]=d[2][1]=d[3][1]=0; d[0][1]=d[2][0]=1; d[1][1]=d[3][0]=-1; scanf("%d%d%d",&n,&m,&p); for (int i=1; i<=p; i++) scanf("%d",&s[i]); for (int i=1; i<=n; i++) { scanf("%s",str+1); for (int j=1; j<=m; j++) if (str[j]=='#') a[i][j]=-1; else if (str[j]=='.') a[i][j]=0; else a[i][j]=str[j]-'0',v[a[i][j]].pb(mp(i,j)); } while (1) { bool bo=0; for (int i=1; i<=p; i++) for (int j=1; j<=s[i]; j++) if (!bfs(i)) break; else bo=1; if (!bo) break; } memset(ans,0,sizeof(ans)); for (int i=1; i<=n; i++) for (int j=1; j<=m; j++) if (a[i][j]>0) ans[a[i][j]]++; for (int i=1; i<=p; i++) printf("%d ",ans[i]); puts(""); return 0; }
比赛的时候想的是优先队列保存至所有的,然后依次bfs..这个判断大小关系是 步数/速度 才是所谓的步数
比赛的时候 step/v多加了取整的1 .没搞清所谓第一步是[0,1).就是要直接除.细节还是要搞好额。。
下面代码
#include<bits/stdc++.h> using namespace std; #define ll long long #define pb push_back #define mp make_pair #define fi first #define se second #define all(v) v.begin(),v.end() #define mem(a) memset(a,0,sizeof(a)) const int N = 1003; const ll mod =1e9+7; const int INF = 1e9+4; const double eps = 1e-7; char gra[N][N]; int dx[]={1,-1,0,0}; int dy[]= {0,0,1,-1}; int sp[22]; int ans[222]; int n,m,p; struct node{ int x,y; int step; int per; friend bool operator <(node a,node b){ int ad = a.step/sp[a.per]; //if(a.step%sp[a.per]!=0)ad++; int bd = b.step/sp[b.per]; // if(b.step%sp[b.per]!=0) bd++;
//比赛的时候这里多加了 ..没搞清所谓第一步是[0,1)..细节还是要搞好
if(ad!=bd) return ad>bd; if(a.per==b.per)return a.step>b.step; return a.per>b.per; } }; bool ingra(int x,int y){ return x>=1 && y>=1 && x<=n && y<=m; } void bfs(){ priority_queue<node>Q; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(gra[i][j]>='1' && gra[i][j]<='9'){ Q.push(node{i,j,0,gra[i][j]-'1'+1}); } } } while(!Q.empty()){ node tmp = Q.top(); Q.pop(); int x= tmp.x; int y =tmp.y; int per= tmp.per; int step =tmp.step; //printf("%d %d %d\n",x,y,per); for(int i=0;i<4;++i){ int nx =x+dx[i]; int ny =y+dy[i]; if(ingra(nx,ny)==false)continue; if(gra[nx][ny]!='.')continue; gra[nx][ny]= per+'1'-1; Q.push(node { nx,ny,step+1,per}); } } } int main(){ cin>>n>>m>>p; for(int i=1;i<=p;++i) cin>>sp[i]; for(int i=1;i<=n;++i) scanf("%s",gra[i]+1); bfs(); for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ if(gra[i][j]>='1' && gra[i][j]<='9') ans[gra[i][j]-'1']++; } } for(int i=0;i<p;++i) printf("%d%c",ans[i],i==p-1?'\n':' '); return 0; }