poj 3164 Command Network (朱刘算法)
题目链接:
http://poj.org/problem?id=3164
题目大意:
有n个点(用坐标表示)各点编号分别为1—>n,m条单向路,问能否存在一个花费价值最小的网络,能使从1点到达任一个点。
解题思路:
很明显的朱刘模板题,但是刚看到这个题目的时候,弱还不懂这个东西%>_<%
最小树形图就是给有向带权图中指定一个特殊的点root,求一棵以root为根的有向生成树T,并且T中所有边的总权值最小。
朱刘算法:当有向图中不存在自环,为除根之外的每个点选定一条入边,这条入边一定要是所有入边中最小的。所有的最小入边都选择出来了,如果这个入边集不存在有向环的话,这个集合就是该图的最小树形图。如果有自环的话就要消除自环,比如,现在我们假设分别有3-->1,权值为1 . 1-->3,权值为2 . 2-->1,权值为6 . 4-->3,权值为5. ,root为点4,存在自环1-->3-->1,现在就需要把1,3缩成一个点,则需要把4-->3边的权值5-2,2-->1边的权值变为6-1,。
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = ;
const int N = ;
const double Exp = 1e-;
const int INF = 0x3f3f3f3f;
struct Point
{
double x, y;
double length(Point a)
{
return sqrt((a.x-x)*(a.x-x)+(a.y-y)*(a.y-y));
}
}; struct Edge
{
int u, v;
double w;
}; Point point[maxn];
Edge edge[N];
int n, m;
double directed_MST (int root)
{
double pre[maxn], ans = ;
//pre[i]为到i点权值最小的边值
int vis[maxn], id[maxn], pr[maxn];
//vis[i]为i点是否在当前的数上,id[i]为i点是否在自环内,
int u, v;
while (true)
{
for (int i=; i<=n; i++)
pre[i] = INF;
for (int i=; i<m; i++)
{
u = edge[i].u;
v = edge[i].v;
if (edge[i].w<pre[v] && u!=v)
{
pre[v] = edge[i].w;
pr[v] = u;//到v点前驱
}
}
for (int i=; i<=n; i++)
{
if (i == root)
continue;
if (pre[i] == INF)
return -;//没有点与i相连,不存在最小树形图
}
memset (vis, -, sizeof(vis));
memset (id, -, sizeof(id));
int cru = ;//对现存的点从新编号
pre[root] = ;
for (int i=; i<=n; i++)
{
ans += pre[i];
v = i;
while (vis[v]!=i && id[v]==- && v!=root)
{//向树上加点
vis[v] = i;
v = pr[v];
}
if (v!=root && id[v]==-)
{//存在自环,并且把环变成一个点
for (u=pr[v]; u!=v; u=pr[u])
id[u] = cru;
id[u] = cru ++;
}
}
if (cru == )
break;//不存在自环
for (int i=; i<=n; i++)
if (id[i] == -)
id[i] = cru ++;//对不在自环上的点编号
for (int i=; i<m; i++)
{//把自环缩成一个点后,需要改变边的权
u = edge[i].u;
v = edge[i].v;
edge[i].u = id[u];
edge[i].v = id[v];
if (id[u] != id[v])
edge[i].w -= pre[v];
}//缩点后点数改变,根节点改变
n = cru - ;
root = id[root];
}
return ans;
}
int main ()
{
while (scanf ("%d %d", &n, &m) != EOF)
{
for (int i=; i<=n; i++)
scanf ("%lf %lf", &point[i].x, &point[i].y); for (int i=; i<m; i++)
{
int u, v;
scanf ("%d %d", &u, &v);
edge[i].u = u;
edge[i].v = v;
if (u == v)
edge[i].w = INF;
else
edge[i].w = point[u].length(point[v]);
}
double num = directed_MST();
if (num+< Exp)
printf ("poor snoopy\n");
else
printf ("%.2f\n", num);
}
return ;
}
poj 3164 Command Network (朱刘算法)的更多相关文章
- POJ 3164 Command Network ( 最小树形图 朱刘算法)
题目链接 Description After a long lasting war on words, a war on arms finally breaks out between littlek ...
- POJ 3164 Command Network 最小树形图 朱刘算法
=============== 分割线之下摘自Sasuke_SCUT的blog============= 最 小树形图,就是给有向带权图中指定一个特殊的点root,求一棵以root为根的有向生成树T, ...
- POJ 3164——Command Network——————【最小树形图、固定根】
Command Network Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 15080 Accepted: 4331 ...
- POJ 3164 Command Network (最小树形图)
[题目链接]http://poj.org/problem?id=3164 [解题思路]百度百科:最小树形图 ]里面有详细的解释,而Notonlysucess有精简的模板,下文有对其模板的一点解释,前提 ...
- POJ 3164 Command Network 最小树形图
题目链接: 题目 Command Network Time Limit: 1000MS Memory Limit: 131072K 问题描述 After a long lasting war on w ...
- poj 3164 Command Network(最小树形图模板)
Command Network http://poj.org/problem?id=3164 Time Limit: 1000MS Memory Limit: 131072K Total Subm ...
- POJ 3164 Command Network(最小树形图模板题+详解)
http://poj.org/problem?id=3164 题意: 求最小树形图. 思路: 套模板. 引用一下来自大神博客的讲解:http://www.cnblogs.com/acjiumeng/p ...
- poj 3164 Command Network
http://poj.org/problem?id=3164 第一次做最小树形图,看着别人的博客写,还没弄懂具体的什么意思. #include <cstdio> #include < ...
- POJ 3164 Command Network 最小树形图模板
最小树形图求的是有向图的最小生成树,跟无向图求最小生成树有很大的区别. 步骤大致如下: 1.求除了根节点以外每个节点的最小入边,记录前驱 2.判断除了根节点,是否每个节点都有入边,如果存在没有入边的点 ...
随机推荐
- mysql资料整理
###SQL的语言分类 1.DQL(Data Query Language):数据查询语言 select 2.DML(Data Manipulate Language):数据操作语言 insert . ...
- 关闭Windows 2003/2008中IE增强的安全配置的方法
在使用Windows Server 2003/2008操作系统时,打开IE浏览网页时,发现浏览器总提示 "是否需要将当前访问的网站添加到自己信任的站点中去",要是不信 ...
- 机器学习技法总结(五)Adaptive Boosting, AdaBoost-Stump,决策树
上一讲主要利用不同模型计算出来的g.採用aggregation来实现更好的g.假设还没有做出来g.我们能够採用bootstrap的方法来做出一系列的"diversity"的data ...
- jason数据格式 -- 扫盲
JSON是 JavaScript Object Notation的简称,是一种轻量的数据表示方法.jason格式採用key:value的方式记录数据,非常直观,比XML简洁,因而大受欢迎 介绍jaso ...
- 【iOS系列】-iOS查看沙盒文件图文教程(真机+模拟器)
[iOS系列]-iOS查看沙盒文件图文教程(真机+模拟器) 1:模拟器 1.1 方法1: 程序中打印一下的地址,能直接前往沙盒路径. NSString *path = [NSSearchPathFor ...
- 初步学习C++中的继承关系
继承机制是面向对象程序设计使代码能够复用的最重要的手段,它同意程序猿在保持原有类特性的基础上进行扩展,添加功能. 这样产生新的类,称派生类.继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂 ...
- oracle 12c 13姨
搞了一下oracle 12c.有些体会还是先记下来. 12c搞搞新意思,弄了个CDB(容器数据库,可不是商务中心CBD哟)和PDB(可插拔数据库).PDB插在CDB里. 简单而言,CDB就是一个数据库 ...
- 可以声明接口,但不可以new接口
接口是一种特殊的抽象类,它包含常量和方法的声明,但没有方法的实现:可以把接口看成是一种特殊的抽象类: 接口实质上是一种规范,它关心的是"做什么",不关心"怎样做" ...
- 设置一个DIV块固定在屏幕中央(两种方法)
设置一个DIV块固定在屏幕中央(两种方法) 方法一: 对一个div进行以下设置即可实现居中. <style> #a{ position: fixed; top: 0px; left: 0p ...
- linux进程编程入门
1.进程的创建与操作 任务描述: 在父进程中创建一个全局变量,一个局部变量,并赋予初始值,用fork函数创建子进程.在子进程中对父进程的变量进行自加操作,并且输出变量值,然后父进程睡眠一段时间 各进程 ...