zoukankan      html  css  js  c++  java
  • luogu P1364 医院设置

    题目描述

    设有一棵二叉树,如图:

    其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为1。如上图中,

    若医院建在1 处,则距离和=4+12+2*20+2*40=136;若医院建在3 处,则距离和=4*2+13+20+40=81……

    输入输出格式

    输入格式:

    第一行一个整数n,表示树的结点数。(n≤100)

    接下来的n行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为0表示无链接;第三个数为右链接。

     

    输出格式:

    一个整数,表示最小距离和。

     

    输入输出样例

    输入样例#1: 
    5						
    13 2 3
    4 0 0
    12 4 5
    20 0 0
    40 0 0
    
    输出样例#1: 
     81
    简单!看着 n 的范围 Floyed 都可以吧,不过还是坚持用了SPFA。
    思路:
    有几个人那这个节点的边权就给乘以几,作为他的边权,要确定哪个节点最合适,
    那就每个节点跑跑最短路试试吧,确定总距离最小的那个结点。
    (听起来好像有点暴力,不过在luogu上跑到了0ms,哎呦,不错哦)

    废话不多说上代码:
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    using namespace std;
    int n,head[10001],tot,shu[101],ans,p;
    struct ahah{
        int nxt,to,w;
    }edge[1001];            //记住数组要开大一点。 
    void add(int x,int y,int z)
    {
        edge[++tot].nxt=head[x];edge[tot].to=y;edge[tot].w=z;head[x]=tot;
    }                        //链表建边。 
    queue <int> que;
    int dis[1001],vis[1001],sum;
    void spfa(int s)
    {
        for(int i=1;i<=p;i++) dis[i]=249999;
        memset(vis,0,sizeof(vis));
        dis[s]=0;vis[s]=1;que.push(s);
        while(!que.empty())
        {
            int cur=que.front() ;
            vis[cur]=0; que.pop() ;
            for(int i=head[cur];i;i=edge[i].nxt)
            {
                int now=edge[i].to;
                if(dis[now]>dis[cur]+edge[i].w)
                {
                    dis[now]=dis[cur]+edge[i].w;
                    if(!vis[now])
                    {
                        vis[now]=1;
                        que.push(now); 
                    }
                }
            }
         } 
         sum=0;
         for(int i=1;i<=p;i++)sum+=dis[i]*shu[i];            //统计总长度。 
    }
    int main()
    {
        int vv=999999;
        scanf("%d",&n);
        p=n;
        int x,y,z;
        while(n--)
        {
            scanf("%d%d%d",&z,&x,&y);
            ans++;
            shu[ans]=z;
            add(ans,x,1);add(x,ans,1);    //双向建边。 
            add(ans,y,1);add(y,ans,1);
        }
        for(int i=1;i<=p;i++)
        {
            spfa(i);                    //挨个边跑跑。 
            vv=min(vv,sum);
        }
        printf("%d",vv);
    }
    
    

    此为个人略解,转载请标明出处:http://www.cnblogs.com/rmy020718/p/8834789.html

      那年你一袭袈裟相思放下,可曾记得我儒染风华青丝白发,一语落罢,却是一盏清茶。 

     
  • 相关阅读:
    WF4.0 自定义CodeActivity与Bookmark<第三篇>
    WF4 常用类<第二篇>
    WF4.0 Activities<第一篇>
    WWF3常用类 <第十一篇>
    WWF3XOML方式创建和启动工作流 <第十篇>
    element-ui表格显示html格式
    tail -f 加过滤功能
    vue 遇到防盗链 img显示不出来
    python No module named 'urlparse'
    grep awk 查看nginx日志中所有访问的ip并 去重
  • 原文地址:https://www.cnblogs.com/rmy020718/p/8834789.html
Copyright © 2011-2022 走看看