图论填个小坑。以前就一直在想,无向图有最小生成树,那么有向图是不是也有最小生成树呢,想不到还真的有,叫做最小树形图,网上的介绍有很多,感觉下面这个博客介绍的靠谱点:

http://www.cnblogs.com/vongang/archive/2012/07/18/2596851.html

所以下面的代码也是抄上面的模板的。里面还给出了不定根情况下的最小树形图的做法,新增一个虚拟根,连向其它所有点的费用是总费用+1,然后跑一次算法就可以了,这样可以保证虚拟根一定连出去某个顶点,而且不可能连两个,最后跑出来把多的费用减掉就可以了。感觉想法挺神奇的。

#pragma warning(disable:4996)
#include <iostream>
#include <cstring>
#include <string>
#include <vector>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std; #define maxn 120
#define maxm 12000 int n, m; struct Edge{
int u, v;
double w;
Edge(int ui, int vi, double wi) :u(ui), v(vi), w(wi){}
Edge(){}
}; vector<Edge> E; double x[maxn], y[maxn]; double dist(int i, int j){
return sqrt((x[i] - x[j])*(x[i] - x[j]) + (y[i] - y[j])*(y[i] - y[j]));
} double in[maxn]; // minimum pre edge weight
int pre[maxn]; // pre vertex
int vis[maxn]; // vis array
int id[maxn]; // mark down the id
int nv; // nv is the number of vertex after shrinking double directed_mst(int root)
{
double ret = 0; int nv = n;
while (1){
for (int i = 0; i < nv; ++i) in[i] = 1e10;
for (int i = 0; i < m; ++i){
int u = E[i].u, v = E[i].v;
if (E[i].w < in[v] && u != v){
in[v] = E[i].w;
pre[v] = u;
}
}
// found not connected means impossible
for (int i = 0; i < nv; ++i){
if (i == root) continue;
if (in[i]>1e9) return -1;
}
int cnt = 0;
memset(id, -1, sizeof(id));
memset(vis, -1, sizeof(vis));
in[root] = 0; for (int i = 0; i < nv; ++i){
ret += in[i];
int v = i; while (vis[v] != i&&id[v] == -1 && v != root){
vis[v] = i;
v = pre[v];
}
// v!=root means we find a circle,id[v]==-1 guarantee that it's not shrinked.
if (v != root&&id[v] == -1){
for (int u = pre[v]; u != v; u = pre[u]){
id[u] = cnt;
}
id[v] = cnt++;
}
}
if (cnt == 0) break;
for (int i = 0; i < nv; ++i){
if (id[i] == -1) id[i] = cnt++;
}
// change the cost of edge for each (u,v,w)->(u,v,w-in[v])
for (int i = 0; i < m; ++i){
int v = E[i].v;
E[i].u = id[E[i].u];
E[i].v = id[E[i].v];
if (E[i].u != E[i].v) E[i].w -= in[v];
}
// mark down the new root
root = id[root];
// mark down the new vertex number
nv = cnt;
}
return ret;
} int main()
{
while (cin >> n >> m){
E.clear();
for (int i = 0; i < n; ++i){
scanf("%lf%lf", x + i, y + i);
}
int ui, vi;
for (int i = 0; i < m; ++i){
scanf("%d%d", &ui, &vi);
--ui; --vi;
if (ui != vi) E.push_back(Edge(ui, vi, dist(ui,vi)));
}
m = E.size();
double ans = directed_mst(0);
if (ans < 0) puts("poor snoopy");
else printf("%.2f\n", ans);
}
return 0;
}

POJ3164 Command Network(最小树形图)的更多相关文章

  1. POJ3164 Command Network —— 最小树形图

    题目链接:https://vjudge.net/problem/POJ-3164 Command Network Time Limit: 1000MS   Memory Limit: 131072K ...

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

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

  3. POJ 3164 Command Network 最小树形图

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

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

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

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

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

  6. POJ - 3164-Command Network 最小树形图——朱刘算法

    POJ - 3164 题意: 一个有向图,存在从某个点为根的,可以到达所有点的一个最小生成树,则它就是最小树形图. 题目就是求这个最小的树形图. 参考资料:https://blog.csdn.net/ ...

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

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

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

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

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

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

随机推荐

  1. JQUERY 判断选择器选择的对象 是否存在

    判断方法: 直接选择判断,是不正确的方法,因为 $(“#id”) 不管对象是否存在都会返回 object . if($("#id")){ alert('存在'); }else{ a ...

  2. android开发系列之多线程

    今天在这篇博客里面,我只想谈谈自己对程序开发里面避无可避的一个问题-多线程的一些看法与思考. 其实说到多线程这个名称相信只要接触过软件这个行业的人都已经耳熟能详了,但是如果被问到到底什么才是多线程呢? ...

  3. JavaScript高级程序设计之表单基础

    A FORM <form id='form' action='http://a-response-url' method="post"> <!--maxlengt ...

  4. epoll重要

    EPOLL事件分发系统可以运转在两种模式下:Edge Triggered (ET).Level Triggered (LT). LT是缺省的工作方式,并且同时支持block和no-blocksocke ...

  5. Linux 编辑器

    vim编辑器 vi作为Unix上的一个编辑器,一直广受欢迎.之后GUN将其移植到开源世界中,经过开发人员对其进行了改善,被称为vi improved,就是现在的vim.为了方便使用,几乎所有的Linu ...

  6. Asp.net操作Excel(终极方法NPOI)(转)

    原文:Asp.net操作Excel(终极方法NPOI) 先去官网:http://npoi.codeplex.com/下载需要引入dll(可以选择.net2.0或者.net4.0的dll),然后在网站中 ...

  7. R语言绘图002-页面布局

    par().layout().split.screen()函数 1. par()函数的参数详解 函数par()可以用来设置或者获取图形参数,par()本身(括号中不写任何参数)返回当前的图形参数设置( ...

  8. Careercup - Microsoft面试题 - 5120588943196160

    2014-05-10 22:58 题目链接 原题: Three points are given A(x1, y1), B(x2, y2), C(x3, y3). Write a method ret ...

  9. C#制作高仿360安全卫士窗体<二>

    继上次C#制作高仿360安全卫士窗体<一>发布之后响应还不错,我的博客放肆雷特也来了不少的新朋友,在这里先谢谢大家的支持!我自己也反复看了一下觉得对不起大家,写的非常乱而且很少文字介绍.在 ...

  10. Ext中如何校验TextField的字段被修改了?

    场景描述:      在form表单中有个sfzhm的字段,需要去后台进行sfzhm是否重复的校验,一开始使用了blur的event来去后台进行校验,后来发现在焦点离开时,及时数据没有发生变化,也会造 ...