Codeforces987D (reverse thinking multi-source BFS)

Link to the original question
Question meaning:
n points, m sides, there are at most k items of different types, and s items of different types are required to be collected. Each point will produce a type of item, and ask the sum of the shortest paths to collect enough s items from each point.
Idea:
Note that the range of n is very large, 1e5: the range of k is only 100.
The normal idea is to run bfs from every point, so it will definitely be T. You can reverse thinking, run bfs from each type of item, and record the shortest path of each type of item to all cities. For each city, just take the smallest s.
Code:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll>PLL;
typedef pair<int,int>PII;
typedef pair<double,double>PDD;
#define I_int ll
inline ll read()
{
    
    
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
    
    
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
    
    
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
#define read read()
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
ll ksm(ll a,ll b,ll p)
{
    
    
    ll res=1;
    while(b)
    {
    
    
        if(b&1)res=res*a%p;
        a=a*a%p;
        b>>=1;
    }
    return res;
}
#define PI acos(-1)
#define x first
#define y second
const int maxn=1e6+7,inf=0x3f3f3f3f;
int n,m,s,k,a[maxn];
int h[maxn],idx;
struct node{
    
    
    int e,ne;
}edge[maxn];
void add(int u,int v){
    
    
    edge[idx]={
    
    v,h[u]},h[u]=idx++;
}
vector<int>res[maxn];
bool st[maxn];
void bfs(int k){
    
    
    queue<PII>q;
    memset(st,0,sizeof st);
    rep(i,1,n)
        if(a[i]==k) st[i]=1,q.push({
    
    i,0});
    while(!q.empty()){
    
    
        auto t=q.front();q.pop();
        int id=t.first,dis=t.second;
        res[id].push_back(dis);
        for(int i=h[id];~i;i=edge[i].ne){
    
    
            int j=edge[i].e;
            if(!st[j]){
    
    
                st[j]=1,q.push({
    
    j,dis+1});
            }
        }
    }
}
int main()
{
    
    
    memset(h,-1,sizeof h);
    idx=0;
    n=read,m=read,k=read,s=read;
    rep(i,1,n) a[i]=read;
    rep(i,1,m){
    
    
        int u=read,v=read;
        add(u,v);add(v,u);
    }
    rep(i,1,k) bfs(i);
    rep(i,1,n){
    
    
        sort(res[i].begin(),res[i].end());
        ll t=0;
        rep(j,0,s-1) t+=res[i][j];
        printf("%lld ",t);
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45675097/article/details/114240536
Recommended