Fair CodeForces

题意:

  有n个城市 m条边,每条边的权值为1,每个城市生产一种商品(可以相同,一共k种),求出分别从每个城市出发获得s种商品时所走过路的最小权值

解析:

  我们倒过来想,不用城市找商品,而是商品找城市,求出每个商品到达每个城市的最短路,w[i][j]即为生产商品j的城市到达城市i的最短路,最后对于每个i排序w[i] 取前s个小的即可

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std;
const int maxn = 1001000, INF = 0x7fffffff;
typedef long long LL;
vector<int> G[maxn];
int n, m, k, s;
int w[maxn][105];   //w[i][j] 生产j商品的城市到i城市的最短路

void bfs(int x)
{
    queue<int> Q;
    Q.push(x+n);
    while(!Q.empty())
    {
        int u = Q.front(); Q.pop();
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            if(w[v][x] == 0)
            {
                w[v][x] = w[u][x] + 1;      //目的就是找到生产j商品的城市(无论哪一个)到i城市的最短路
                Q.push(v);
            }
        }
    }
}

int main()
{
    int u, v, c;
    scanf("%d%d%d%d", &n, &m, &k, &s);
    for(int i=1; i<=n; i++)
    {
        scanf("%d", &c);
        G[c+n].push_back(i);
    }
    for(int i=0; i<m; i++)
    {
        scanf("%d%d", &u, &v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i=1; i<=k; i++) bfs(i);
    for(int i=1; i<=n; i++)
    {
        int res = 0;
        sort(w[i]+1, w[i]+k+1);     //把k个商品分别到i城市的最短路排序,累加最小的s个
        for(int j=1; j<=s; j++)
            res += w[i][j] - 1;     //因为每次是从商品开始广搜的 每个商品多加了一个1
        printf("%d ", res);
    }


    return 0;
}
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
原文地址:https://www.cnblogs.com/WTSRUVF/p/9524234.html