Codeforces Round #485 (Div. 2) - D - Fair

传送门:点击打开链接

题意:n个城市,m条无向路,共有k种货物,每个城市只有一种货物,让你求在城市i举办交易会,至少有s种货物参加,求最少的路径之和

分析:两种思路,一是直接对每一个进行点bfs,找到s种不同货物直接返回,复杂度大约为O(n*s)(标记的时候要用bool类型的数组,用int型会超时),二是进行k遍bfs,暴力k种颜色到每个点的最短距离,最后对这k种颜色到每个点的距离排序取前s个做和。

代码一:

///思路一
#include<bits/stdc++.h>
using namespace std ;
const int N = 1e5+10 ;
typedef long long ll;
vector<int> mp[N];
int a[N],d[N],n,m,k,s;
bool vis[N],ct[N];
///标记数组一定要用bool类型节约时间,否则会tle

void bfs(int x)
{
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    memset(ct,0,sizeof(ct));
    vis[x]=1;
    ct[a[x]]=1;
    queue<int> q;
    q.push(x);
    int sum=1,ans=0;
    d[x]=0;
    if(s==1) {
        if(x==n) cout<<0<<endl;
        else cout<<0<<" ";
        return ;
    }
    while(!q.empty())
    {
        int tp=q.front();
        q.pop();
        for(int i=0; i<mp[tp].size(); i++)
        {
            int u=mp[tp][i];
            if(!ct[a[u]])
            {
                q.push(u);
                sum++;
                vis[u]=1;
                d[u]=d[tp]+1;
                ans += d[u];
                if(sum==s)
                {
                    cout<<ans;
                    if(x==n) cout<<endl;
                    else cout<<" ";
                    return ;
                }
            }
        }
        for(int i=0; i<mp[tp].size(); i++)
        {
            int u=mp[tp][i];
            if(!vis[u])
            {
                vis[u]=1;
                q.push(u);
                d[u]=d[tp]+1;
            }
        }
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin>>n>>m>>k>>s;
    for(int i=1; i<=n; i++)
        cin>>a[i];
    for(int i=0; i<m; i++)
    {
        int x,y;
        cin>>x>>y;
        mp[x].push_back(y);
        mp[y].push_back(x);
    }
    for(int i=1; i<=n; i++)
        bfs(i);
    return 0 ;
}

代码二:

///思路二
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
#define pb push_back
int d[N][105],v[N],n,m,k,s,ans[N];
vector<int> e[N];

void bfs(int x) {
    queue<int> q;
    for(int i=1;i<=n;i++) {
        if(v[i]==x) {
            d[i][x]=0;
            q.push(i);
        }
    }
    int tp;
    while(!q.empty()) {
        tp = q.front();q.pop();
        for(int i=0;i<e[tp].size();i++) {
            int u=e[tp][i];
            if(d[u][x]==-1) {
                d[u][x]=d[tp][x]+1;
                q.push(u);
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin>>n>>m>>k>>s;
    for(int i=1;i<=n;i++)
        cin>>v[i];
    for(int i=1;i<=m;i++) {
        int v1,v2;
        cin>>v1>>v2;
        e[v1].pb(v2);
        e[v2].pb(v1);
    }
    for(int i=1;i<=k;i++) {
        for(int j=1;j<=n;j++)
            d[j][i]=-1;
        bfs(i);
    }

    for(int i=1;i<=n;i++) {
        sort(d[i]+1,d[i]+k+1);
        int sum=0;
        for(int j=1;j<=s;j++)
            sum+=d[i][j];
        ans[i]=sum;
    }
    for(int i=1;i<n;i++)
        cout<<ans[i]<<" ";
    cout<<ans[n];
    return 0;
}

猜你喜欢

转载自blog.csdn.net/tianwei0822/article/details/80558951