• CF986A Fair【图论/BFS】


    【题意】:

    有些公司将在Byteland举办公平的会议。Byteland的n个城镇,m条两镇之间的双向道路。当然,你可以使用道路从任一个城镇到达任何城镇。
    有k种商品产自Byteland,并且每个城镇只生产一种类型。为了举办公平,你必须至少带来s种不同种类的商品。
    【It costs d(u,v) coins to bring goods from town u to town v where d(u,v)d (u , v ) is the length of the shortest path from u to v .】
      它花费货物从市区u到市区v的硬币成本为d(u,v),其中d(u,v)是从u到v的最短路的长度。
     【Length of a path is the number of roads in this path.】
       路径的长度是此路径中的道路数量。
    主办单位将承担所有差旅费用,但他们可以选择城镇提货。现在他们想要计算在n个城镇举办公平的最低费用。
    输入 城镇数量n,道路数量m,不同类型商品的数量k,持有公平所需的不同类型商品的数量s。
    其中ai 是第i个城镇生产的商品类型。确保1和k之间的所有整数在整数ai中至少出现一次。
    通过这条路相连的城镇。保证每两个城镇之间不超过一条公路。保证您可以通过道路从任何城镇到任何其他城镇。
    打印n个数,其中第i个数是您需要花费在旅行费用上的最小数量的硬币用空格分隔数字。
    

    【分析】:我们要另辟蹊径,从k种不同类型的商品为起点进行BFS,然后求k个点到不同城镇的最短路径,为什么呢?因为k最多100种,如果从城镇为起点BFS,那么1e5的决策次数是会T的。

    【代码】:

    #include <iostream>
    #include<queue>
    #include<string.h>
    #include<bits/stdc++.h>
    using namespace std;
    #define N 100010
    #define M 2005
    const int  INF =  0x3f3f3f3f;
    #define rep(i,a,b) for(int i=(a); i<(b); i++)
    #define ll long long
    int n,m,k,s,u,v;
    int a[N];
    vector<int> G[N];
    int d[N];
    int dis[105][N];//dist[i]是源到i的目前最短路长度
    
    void bfs(int st)
    {
        queue<int> q;
        for(int i=1;i<=n;i++)
        {
            if(a[i]==st) //起点等于某一类(枚举k个商品)
            {
                dis[st][i]=0;
                q.push(i); //记录下标
            }
        }
        while( !q.empty() )
        {
             //每次迭代,取出队头的点u,依次枚举从u出发的边
            int u=q.front();q.pop();
            for(int i=0; i<G[u].size(); i++)
            {
                int v=G[u][i];
                //若dis[v]+1 < dis[v],则改进dis[v]
                if(dis[st][v] > dis[st][u] + 1)
                {
                    dis[st][v] = dis[st][u] + 1;//没判队列里是否已经有v,可能会慢一些
                    q.push(v); //此时由于st到v的最短距离变小了,有可能v可以改进其它的点,所以若v不在队列中,就将它放入队尾
                } //这样一直迭代下去直到队列变空,也就是S到所有节点的最短距离都确定下来,结束算法
            }
        }
    }
    int main()
    {
        memset(dis,120,sizeof(dis));
        scanf("%d%d%d%d",&n,&m,&k,&s);
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        for(int i=1;i<=m;i++)
        {
            cin>>u>>v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        for(int i=1; i<=k; i++) bfs(i);//从k个不同类型点枚举,保存dis最短路径
        for(int i=1; i<=n; i++)
        {
    
            for(int j=1; j<=k; j++) d[j]=dis[j][i];
            sort(d+1,d+k+1);
            long long ans=0;
            for(int j=1; j<=s; j++) ans+=d[j];
            cout << ans << ' ';
        }
        cout<<endl;
    }
    
    
  • 相关阅读:
    国家语言,语言代码,locale id对应表
    SpringMVC,SpringBoot文件下载
    lombok使用基础教程
    博客园主题修改中用到的css属性
    Hexo next博客添加折叠块功能添加折叠代码块
    IntelIj IDEA运行JUnit Test OutOfMemoryError
    Spring Boot-JPA、Hibernate、Spring data jpa之间的关系
    IntelliJ IDEA-设置字体大小
    win10-mysql卸载干净
    IntelliJ IDEA Check out from git
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9118038.html
Copyright © 2020-2023  润新知