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; }

猜你喜欢

转载自www.cnblogs.com/wjhstudy/p/10300430.html