题目链接

Description

After a long lasting war on words, a war on arms finally breaks out between littleken’s and KnuthOcean’s kingdoms. A sudden and violent assault by KnuthOcean’s force has rendered a total failure of littleken’s command network. A provisional network must be built immediately. littleken orders snoopy to take charge of the project.

With the situation studied to every detail, snoopy believes that the most urgent point is to enable littenken’s commands to reach every disconnected node in the destroyed network and decides on a plan to build a unidirectional communication network. The nodes are distributed on a plane. If littleken’s commands are to be able to be delivered directly from a node A to another node B, a wire will have to be built along the straight line segment connecting the two nodes. Since it’s in wartime, not between all pairs of nodes can wires be built. snoopy wants the plan to require the shortest total length of wires so that the construction can be done very soon.

Input

The input contains several test cases. Each test case starts with a line containing two integer N (N ≤ 100), the number of nodes in the destroyed network, and M (M ≤ 104), the number of pairs of nodes between which a wire can be built. The next N lines each contain an ordered pair xi and yi, giving the Cartesian coordinates of the nodes. Then follow M lines each containing two integers i and j between 1 and N (inclusive) meaning a wire can be built between node i and node j for unidirectional command delivery from the former to the latter. littleken’s headquarter is always located at node 1. Process to end of file.

Output

For each test case, output exactly one line containing the shortest total length of wires to two digits past the decimal point. In the cases that such a network does not exist, just output ‘poor snoopy’.

Sample Input

4 6

0 6

4 6

0 0

7 20

1 2

1 3

2 3

3 4

3 1

3 2

4 3

0 0

1 0

0 1

1 2

1 3

4 1

2 3

Sample Output

31.19

poor snoopy

分析:

题意:两国交战,一个国家的指挥官要将命令通过传输网络下达到部队,部队通过架设电缆来传输信息。电缆传输信息是单向的,并且命令只要能够传下去就可以,不需要下面的不对向上级汇报。现在给出各个部队的位置和可以建立连接的部队,问至少需要多长的电缆。

理解题目意思后,就转换为给你一个有向图,求有向图的最小树形图。在这里要用到朱刘算法(终于见到我们中国人自己写出的算法了)。具体步骤如下:

基于贪心和缩点的思想。

假设根的顶点是V0。

(1)除了根结点外,所有的点Vi,找到以Vi为终点的最短的边,加入集合中(pre[v]存放的是终点v的起点,In[v]存放终点为v的最短的边)

(2)检查集合中有没有有向环和收缩点。若没有有向环和收缩点,结束计算;若没有有向环、但含收缩边,则跳至步骤(4);若含有有向环,则跳至步骤(3)。

(3)含有有向环,则收缩有向环(缩点),把有向环收缩为一个点,其有向环内的边被收缩掉,而环外的边被保留,构建新图,重复步骤(1)、(2)。

(4)没有有向环,有收缩边,则展开收缩边。

具体的可以根据图来理解一下

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<limits.h>
using namespace std;
const int MAXN = 110;
const int MAXM = 10010;
const int INF=0x3f3f3f3f;
//存储边的信息
struct Node
{
int from;
int to;
double w;
}Edges[MAXM]; //存储点的信息
struct Node1
{
double x;
double y;
}Point[MAXN]; //计算两点间的距离,也就是在计算边长
double Dist(Node1 a, Node1 b)
{
double x = a.x - b.x;
double y = a.y - b.y;
return sqrt(x*x+y*y);
} //pre是i点的起点,
int pre[MAXN],vis[MAXN],flag[MAXN];
double In[MAXN],sum;//IN是在表示以i为终点的最短边长 double ZhuLiu(int root,int N,int M)
{
sum = 0;
while(true)
{
for(int i = 0; i < N; ++i)
In[i] = INF; for(int i = 0; i < M; ++i)//找到以没个遍为终点的最短边
{
int u = Edges[i].from;//起点
int v = Edges[i].to;//终点
if(Edges[i].w < In[v] && u != v)
{
pre[v] = u;//v为终点,pre[v]存放起点
In[v] = Edges[i].w;//权值最小的边
}
} for(int i = 0; i < N; ++i)//如果存在除root以外的孤立点,则不存在最小树形图
{
if(i == root)
continue;
if(In[i] == INF)
return -1;
} int CntNode = 0;
memset(flag,-1,sizeof(flag));//flag是重新的编号
memset(vis,-1,sizeof(vis));//vis是标记他们在那个环里面
In[root] = 0;
for(int i = 0; i < N; ++i) //找环,标记每个环
{
sum += In[i];
int v = i;
while(vis[v]!=i && flag[v]==-1 && v!=root)//每个点寻找其前序点,要么最终寻找至根部,要么找到一个环
{
vis[v] = i;
v = pre[v];
}
//找到了一个环
if(v != root && flag[v] == -1) //新图重新编号
{
for(int u = pre[v]; u != v; u = pre[u])
flag[u] = CntNode;
flag[v] = CntNode++;//还是自身的编号,只是在编号的同时实现了编号数目的增加
}
}
if(CntNode == 0) //无环,跳出
break;
for(int i = 0; i < N; ++i)//给那些没有形成环的点也要重新编号
{
if(flag[i] == -1)
flag[i] = CntNode++;
}
for(int i = 0; i < M; ++i) //建立新图,更新其他点到环的距离
{
int v = Edges[i].to;
Edges[i].from = flag[Edges[i].from];
Edges[i].to = flag[Edges[i].to];
if(Edges[i].from != Edges[i].to)
Edges[i].w -= In[v];
}
N = CntNode;
root = flag[root];
}
return sum;
} int main()
{
int x,y,N,M;
while(~scanf("%d%d",&N,&M))
{
int id = 0;
for(int i = 0; i < N; ++i)
scanf("%lf%lf",&Point[i].x,&Point[i].y);
for(int i = 0; i < M; ++i)
{
scanf("%d%d",&x,&y);
if(x == y)
continue;
x--;
y--;
Edges[id].from = x;
Edges[id].to = y;
Edges[id++].w = Dist(Point[x],Point[y]);
}
double ans = ZhuLiu(0,N,id);
if(ans == -1)
printf("poor snoopy\n");
else
printf("%.2lf\n",ans);
}
return 0;
}

POJ 3164 Command Network ( 最小树形图 朱刘算法)的更多相关文章

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

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

  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 最小树形图——朱刘算法

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

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

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

  5. 最小树形图——朱刘算法(Edmonds)

    定义:一个有向图,存在从某个点为根的,可以到达所有点的一个最小生成树,则它就是最小树形图. 朱刘算法实现过程: [在选出入边集后(看步骤1),若有向图中不存在有向环,说明该图就是最小树形图] 1,选入 ...

  6. poj3164(最小树形图&朱刘算法模板)

    题目链接:http://poj.org/problem?id=3164 题意:第一行为n, m,接下来n行为n个点的二维坐标, 再接下来m行每行输入两个数u, v,表点u到点v是单向可达的,求这个有向 ...

  7. 最小树形图--朱刘算法([JSOI2008]小店购物)

    题面 luogu Sol 首先设一个 \(0\) 号点,向所有点连边,表示初始价值 显然这个图的一个 \(0\) 为根的最小有向生成树的边权和就是每个买一次的最小价值 再买就一定能优惠(包含 \(0\ ...

  8. 洛谷P4716 【模板】最小树形图(朱刘算法)

    题意 题目链接 Sol 朱刘算法?感觉又是一种神仙贪心算法 大概就是每次贪心的用每个点边权最小的入边更新答案,如果不行的话就缩起来找其他的边 不详细说了,丢链接走人.. #include<bit ...

  9. bzoj 4349 最小树形图——朱刘算法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4349. 学习博客:http://www.cnblogs.com/xzxl/p/7243466 ...

随机推荐

  1. 用Html5与Asp.net MVC上传多个文件

    html: <form action="/home/upload" method="post" enctype="multipart/form- ...

  2. Scalable IO in Java【java高效IO】

    第一次翻译,如有错误,请指正 1.Outline 大纲Scalable network services  高效网络服务 Event-driven processing  事件驱动处理 Reactor ...

  3. idea的protobuf使用

    1.安装插件 2.添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...

  4. 【LaTex】随便学学,

    教程 http://blog.csdn.net/u014803202/article/details/50410748 一个数学公式编辑器 http://latex.91maths.com/

  5. BZOJ 3731: Gty的超级妹子树

    3731: Gty的超级妹子树 Time Limit: 7 Sec  Memory Limit: 32 MBSubmit: 346  Solved: 96[Submit][Status][Discus ...

  6. Luogu 2801 教主的魔法 | 分块模板题

    Luogu 2801 教主的魔法 | 分块模板题 我犯的错误: 有一处l打成了1,还看不出来-- 缩小块大小De完bug后忘了把块大小改回去就提交--还以为自己一定能A了-- #include < ...

  7. 在OpenShift上托管web.py应用

    一.背景 最近在学习web.py,跟随官网的cookbook和code examples一路敲敲打打,在本地访问了无数遍http://0.0.0.0:8080/,也算是对web.py有了基本的认识.为 ...

  8. 响应式开发(三)-----Bootstrap框架的安装使用

    下载 Bootstrap 可以从http://getbootstrap.com/上下载 Bootstrap 的最新版本. Download Bootstrap:下载 Bootstrap.点击该按钮,您 ...

  9. %1$s %1$d Android string (java & Android 格式化字符串)

    1$s // String%1$d // int //R.string.old:<string name="old">我今年%1$d岁了</string> ...

  10. bzoj 4199 && NOI 2015 品酒大会

    一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品酒家”和“首席猎手”两个奖项,吸引了众多品酒师参加. 在大会的晚餐上,调酒师 Rainbow 调制了 ...