zoukankan      html  css  js  c++  java
  • cogs5. P服务点设置

    ★★   输入文件:djsc.in   输出文件:djsc.out   简单对比
    时间限制:2 s   内存限制:128 MB

     问题描述
    为了进一步普及九年义务教育,政府要在某乡镇建立P所希望小学,该乡镇共有n个村庄,村庄间的距离已知,请问学校建在哪P个村庄最好?(好坏的标准是学生就近入学,即在来上学的学生中,以最远的学生走的路程为标准。或者说最远的学生与学校的距离尽可能的小。)

     
    【输入格式】
    输入由若干行组成,第一行有3个整数,n1n100m1mn2,pn表示村庄数,m表示村庄间道路数。第2m+1行是每条路的信息,每行三个整数,为道路的起点、终点和两村庄间距离。(村庄从0开始编号)
    【输出格式】
    P个整数,学校所在村庄编号(如果P个以上村庄都适合建立学校,选择编号小的P个村庄建学校,输出时按编号从小到大输出)。
    【输入样例】
    输入文件名:djsc.in
    6 8 2
    0 2 10
    0 4 30
    0 5 100
    1 2 5
    2 3 50
    3 5 10
    4 3 20
    4 5 60
    【输出样例】
    输出文件名:djsc.out
    0 3
    floyd+dfs:
        #include<cstdio>
        #include<cstring>
        #include<climits>
        #include<algorithm>
        #include<iostream>
        #define min(a,b) ((a)<(b)?(a):(b))
         using namespace std;
        int n,m,p;
        int a[101][101];
        int rec[101],ans[101];
        bool b[101]={0};
        int maxn=INT_MIN,minn=INT_MAX,mnn=INT_MAX;
         
        void init();
        void work();
        void outit();
        void dfs(int );
         
        int main()
        {
            freopen("djsc.in","r",stdin);
               freopen("djsc.out","w",stdout);
             init();
            work();
            outit();
            return 0;
        }
        void init()
        {
            scanf("%d%d%d",&n,&m,&p);
            memset(a,0x3f,sizeof(a));
            for(int i=0;i<m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                a[x][y]=z;
                a[y][x]=z;
            }
            for(int i=0;i<n;i++)a[i][i]=0;
        }
        void work()
        {
            for(int k=0;k<n;k++)
            for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
            dfs(1);
        }
        void outit()
        {
            std::sort(ans+1,ans+p+1);
            for(int i=1;i<=p;i++)
                printf("%d ",ans[i]);
        }
        void dfs(int x)//x当前点、num已选点数
        {
            if(x==p+1)//说明上一个num为p
            {
                maxn=INT_MIN;
                for(int i=0;i<n;i++)//找题意中p个点到其他所有点的最远距离
                {
                    bool flag=false;
                    minn=INT_MAX;
                    for(int j=1;j<=p;j++)//该方案中每个点到i的距离,找最短的
                    {
                        if(!a[i][rec[j]])//也就是rec[j]=i,直接跳过
                        {flag=1;break;}
                        if(a[i][rec[j]]<minn)
                        minn=a[i][rec[j]];
                    }
                    if(!flag&&minn>maxn)maxn=minn;//最短中的最长的
                }
                if(maxn<mnn)//比上一个方案更优,更新
                {
                    mnn=maxn;
                    for(int j=1;j<=p;j++)
                    ans[j]=rec[j];
                }
                return ;
            }
            for(int i=0;i<n;i++)
            {
                if(!b[i])
                {
                    b[i]=1;
                    rec[x]=i;
                    dfs(x+1);
                    b[i]=0;
         
                }
            }
        }
    

      

  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7152371.html
Copyright © 2011-2022 走看看