zoukankan      html  css  js  c++  java
  • CF D. Fair(思维+DFS)

    http://codeforces.com/contest/987/problem/D

    题目大概:

    给出一个n个城镇m条边的图,给出每个城镇拥有的特产(可能多个城镇有相同特产)。有k种不同特产。

    要求每个城镇需要其他城镇运输特产到自己的城镇,每个城镇必须拥有s种特产,那么在城镇满足s种特产后,需要的最短路径是多长,最短路指的是特产运输过来走过的边的数量。

    分析:

    一开始以为是道水题,因为我只要对每个点都进行一次DFS,那问题就很简单了,但是。。。细想下,这其实是不行的,因为会TLE. 那现在我们来转化下思维,城市太多了,可是特产的种类很少,所以!!!!我们算出每种特产到每个城市的最短距离,然后把所有到i城镇的特产的最短路 排序,取前s个就是i点的最短路径了。

    #include <bits/stdc++.h>
    
    using namespace std;
    const int maxn=1e5+5;
    const int INF=0x3f3f3f3f;
    int e[maxn];
    int vis[maxn];///标记
    int lis[maxn][120];///记录
    vector<int>F[120];///每种特产到每个城市
    vector<int>G[maxn];///建图
    struct poin
    {
        int x,d;
    };
    int ans=0;
    int s;
    void bfs(int x)
    {
        queue<poin>Q;
        ///x种特产的开始城市
        for(int i=0;i<F[x].size();i++)
        {
            int v=F[x][i];
            poin q;
            q.x=v;q.d=0;
            Q.push(q);
        }
        ///x种特产去到的城市
        while(!Q.empty())
        {
            poin u=Q.front();Q.pop();
            ///u.x城市到x特产的最短距离
            lis[u.x][x]=min(u.d,lis[u.x][x]);
            for(int i=0;i<G[u.x].size();i++)
            {
                int v=G[u.x][i];
                if(vis[v])continue;
                vis[v]=1;
                poin q;
                q.x=v;
                q.d=u.d+1;
                Q.push(q);
            }
        }
    }
    int main()
    {
        int n,m,k;
        scanf("%d%d%d%d",&n,&m,&k,&s);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&e[i]);
            F[e[i]].push_back(i);///e[i]产品在多少城市
        }
        int u,v;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            G[u].push_back(v);///无向图
            G[v].push_back(u);
        }
        memset(lis,0x3f3f3f3f,sizeof(lis));
        for(int i=1;i<=k;i++)
        {
            memset(vis,0,sizeof(vis));
            bfs(i);///对每种特产DFS
        }
    
        for(int i=1;i<=n;i++)
        {
            sort(lis[i]+1,lis[i]+k+1);///排序
            long long sum=0;
            ///i城市拥有的s种特产的最短距离
            for(int j=1;j<=s;j++)
            {
                sum+=lis[i][j];
            }
            printf("%I64d ",sum);
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    webpack基本使用笔记
    gulp学习记录
    页面优化
    linux下使用indent整理代码
    C++中的getline()
    Sum of Two Integers
    TwoSum
    IDEA个人常用快捷键总结
    mysql数据库遇到的各种问题
    Python中*args 和**kwargs的用法和区别
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9128514.html
Copyright © 2011-2022 走看看