http://poj.org/problem?id=3164

题意:

求最小树形图。

思路:

套模板。

引用一下来自大神博客的讲解:http://www.cnblogs.com/acjiumeng/p/7136604.html

算法步骤如下:

1.判断图的连通性,若不连通直接无解,否则一定有解。

2.为除了根节点以外的所有点选择一个权值最小的入边,假设用pre数组记录前驱,f数组记录选择的边长,记所选边权和为temp。

3.(可利用并查集)判断选择的的边是否构成环,若没有则直接$ans+=temp$并输出ans,若有,则进行下一步操作。

4.对该环实施缩点操作,设该环上有点$V1,V2……Vi……Vn$,缩成的点为node ,对于所有不在环中的点P进行如下更改:

(1) 点P到node的距离为min{$a[p,Vi]-f[Vi]$} (a为边集数组)

(2)点node到p的距离为min{$a[Vi,p]$}

操作(1)的理解:先假设环上所有边均选上,若下次选择某一条边进入该环,则可以断开进入点与进入点的前驱之间的边,即断开F[进入点],所以等效为直接把$a[p,node]$赋值为min{$a[p,Vi]-f[Vi]$}。

特别提醒:本题有自环,可以提前删掉,因为它没有用。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,ll> pll;
const int inf = 0x3f3f3f3f;
const int maxn=+;
const int mod=1e9+; int n, m; struct point
{
double x,y;
}p[maxn]; struct node
{
int u,v;
double w;
}edge[maxn*maxn]; int pre[maxn],id[maxn],use[maxn];
double in[maxn]; double dis(point a,point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
} double mini_tree(int root,int n,int m)//分别是树根,节点数,边数,序号从1开始
{
double ans=;
int u;
while(true)
{
for(int i=;i<=n;i++) in[i]=inf;
for(int i=;i<=m;i++)
{
int u=edge[i].u;
int v=edge[i].v;
if(edge[i].w<in[v]&&u!=v)
{
in[v]=edge[i].w;
pre[v]=u;
}
}//找最小的入边
for(int i=;i<=n;i++)
{
if(i==root)continue;
ans+=in[i];//把边权加起来
if(in[i]==inf)//如果存在没有入弧的点则不存在最小树形图
return -;
}
memset(id,-,sizeof(id));
memset(use,-,sizeof(use));
int cnt=;
for(int i=;i<=n;i++)//枚举每个点,搜索找环
{
int v=i;
while(v!=root&&use[v]!=i&&id[v]==-)
{
use[v]=i;
v=pre[v];
}
if(v!=root&&id[v]==-)//当找到环的时候缩点编号
{
++cnt;
id[v]=cnt;
for(u=pre[v];u!=v;u=pre[u])
id[u]=cnt;
}
}
if(cnt==)//如果没有环结束程序
break;
for(int i=;i<=n;i++)//把余下的不在环里的点编号
if(id[i]==-)
id[i]=++cnt;
for(int i=;i<=m;i++)//建立新的图
{
int u=edge[i].u;
int v=edge[i].v;
edge[i].u=id[u];
edge[i].v=id[v];
if(edge[i].u!=edge[i].v)
edge[i].w-=in[v];
}
n=cnt;//更新节点数和根节点的编号
root=id[root];
}
return ans;
} int main()
{
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m))
{
for(int i=;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
for(int i=;i<=m;i++)
{
scanf("%d%d",&edge[i].u,&edge[i].v);
if(edge[i].u!=edge[i].v)
edge[i].w=dis(p[edge[i].u],p[edge[i].v]);
else edge[i].w=inf;
}
double ans=mini_tree(,n,m);
if(ans==-) printf("poor snoopy\n");
else printf("%.2f\n",ans);
}
return ;
}

POJ 3164 Command Network(最小树形图模板题+详解)的更多相关文章

  1. POJ 3164 Command Network 最小树形图模板

    最小树形图求的是有向图的最小生成树,跟无向图求最小生成树有很大的区别. 步骤大致如下: 1.求除了根节点以外每个节点的最小入边,记录前驱 2.判断除了根节点,是否每个节点都有入边,如果存在没有入边的点 ...

  2. POJ 3164 Command Network 最小树形图

    题目链接: 题目 Command Network Time Limit: 1000MS Memory Limit: 131072K 问题描述 After a long lasting war on w ...

  3. POJ 3164 Command Network 最小树形图 朱刘算法

    =============== 分割线之下摘自Sasuke_SCUT的blog============= 最 小树形图,就是给有向带权图中指定一个特殊的点root,求一棵以root为根的有向生成树T, ...

  4. POJ3436 Command Network [最小树形图]

    POJ3436 Command Network 最小树形图裸题 傻逼poj回我青春 wa wa wa 的原因竟然是需要%.2f而不是.2lf 我还有英语作业音乐作业写不完了啊啊啊啊啊啊啊啊啊 #inc ...

  5. poj 3164 Command Network

    http://poj.org/problem?id=3164 第一次做最小树形图,看着别人的博客写,还没弄懂具体的什么意思. #include <cstdio> #include < ...

  6. poj 3164 Command Network(最小树形图模板)

    Command Network http://poj.org/problem?id=3164 Time Limit: 1000MS   Memory Limit: 131072K Total Subm ...

  7. POJ 3164 Command Network (最小树形图)

    [题目链接]http://poj.org/problem?id=3164 [解题思路]百度百科:最小树形图 ]里面有详细的解释,而Notonlysucess有精简的模板,下文有对其模板的一点解释,前提 ...

  8. POJ 3164——Command Network——————【最小树形图、固定根】

    Command Network Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 15080   Accepted: 4331 ...

  9. POJ 3164 Command Network ( 最小树形图 朱刘算法)

    题目链接 Description After a long lasting war on words, a war on arms finally breaks out between littlek ...

随机推荐

  1. NYOJ 275 队花的烦恼一

    队花的烦恼一 时间限制:3000 ms  |  内存限制:65535 KB 难度:1 描写叙述 ACM队的队花C小+常常抱怨:"C语言中的格式输出中有十六.十.八进制输出,然而却没有二进制输 ...

  2. 001-读书笔记-企业IT架构转型之道-阿里巴巴中台战略思想与架构实战-第一章 阿里巴巴集团中台战略引发的思考

    1.1.阿里中台发展 组件中台可能问题:组织间业务协作.业务核心能力的沉淀.组织KPI考核等 1.2.企业信息中心发展的症结 1.烟囱式系统建设模式 独立构建独立维护 缺点:1.重复功能建设和维护带来 ...

  3. 使用SQLMAP对网站和数据库进行SQL注入攻击

    from:http://www.blackmoreops.com/2014/05/07/use-sqlmap-sql-injection-hack-website-database/ 0x00 背景介 ...

  4. Locust性能测试1-环境准备与基本使用

    前言 提到性能测试,大部分小伙伴想到的就是LR和jmeter这种工具,小编一直不太喜欢写这种工具类的东西,我的原则是能用代码解决的问题,尽量不去用工具. python里面也有一个性能测试框架Locus ...

  5. 【调优】Nginx性能调优

    一.Nginx优化配置 1.主配置文件优化:# vi /usr/local/nginx/conf/nginx.conf----------------------------------------- ...

  6. 摘自(http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html)

    理解Linux系统负荷   作者: 阮一峰 一.查看系统负荷 如果你的电脑很慢,你或许想查看一下,它的工作量是否太大了. 在Linux系统中,我们一般使用uptime命令查看(w命令和top命令也行) ...

  7. 25最短路径之Dijkstra算法

    图的最优化问题:最小生成树.最短路径 典型的图应用问题 无向连通加权图的最小生成树 有向/无向加权图的最短路径 四个经典算法 Kruskal算法.Prim算法---------------最小生成树 ...

  8. 跑道标识和那些复杂的灯光系统 and 简介、编号、参数、标志及数量 and 飞机跑道标准与参数

    http://www.360doc.com/content/16/0616/12/32670666_568219786.shtml http://news.carnoc.com/list/365/36 ...

  9. codeforces E - Anya and Cubes 分块处理 暴力搜索

    说的是给了n个立方体,立方体从1标号到n,每个立方体上有一个数字, 你有 k 个机会 使得其中 k个数位他们自己的阶乘,(自然使用可以少于k次机会,每个立方体最多被使用1次) ,那么求出你从这n个立方 ...

  10. Linux基础命令---lsusb

    lsusb      显示本机的usb设备列表,可以显示出usb的详细信息,包括设备的读取速度和描述符.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE ...