luogu P1364 医院设置
题目描述
设有一棵二叉树,如图:
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为1。如上图中,
若医院建在1 处,则距离和=4+12+2*20+2*40=136;若医院建在3 处,则距离和=4*2+13+20+40=81……
输入输出格式
输入格式:
第一行一个整数n,表示树的结点数。(n≤100)
接下来的n行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为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
那年你一袭袈裟相思放下,可曾记得我儒染风华青丝白发,一语落罢,却是一盏清茶。
除特别注明外,本站所有文章均为Manjusaka丶梦寒原创,转载请注明来自出处