题目大意:给定一个有向图,根节点已知,求该有向图的最小树形图。最小树形图即有向图的最小生成树,定义为:选择一些边,使得根节点能够到达图中所有的节点,并使得选出的边的边权和最小。

题目算法:朱-刘算法(即由中国人朱永津和刘振宏共同发明的算法)。

算法步骤如下:

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]}。

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

最后G++double输出lf会wa,改成f就好了,或者用c++提交

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdio>
#include<cassert>
#include<iomanip>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define ll long long
#define mod 1000000007
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f; double x[N],y[N];
int n,m;
int pre[N];
bool vis[N],in[N];
double w[N][N];
double dis(int a,int b)
{
return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}
void dfs(int u)
{
vis[u]=;
for(int i=;i<=n;i++)
if(!vis[i]&&w[u][i]<inf)
dfs(i);
}
double dirmst(int u)
{
double ans=;
dfs(u);
for(int i=;i<=n;i++)
if(!vis[i])
return -;
memset(vis,,sizeof vis);
while(){
for(int i=;i<=n;i++)
{
if(i!=u&&!in[i])
{
w[i][i]=inf;
pre[i]=i;
for(int j=;j<=n;j++)
if(!in[j]&&w[j][i]<w[pre[i]][i])
pre[i]=j;
}
}
int i;
for(i=;i<=n;i++)
{
if(i!=u&&!in[i])
{
int j=i,cnt=;
while(j!=u&&pre[j]!=i&&cnt<=n)cnt++,j=pre[j];
if(j==u||cnt>n)continue;
break;
}
}
if(i>n)
{
for(int j=;j<=n;j++)
if(j!=u&&!in[j])
ans+=w[pre[j]][j];
return ans;
}
int j=i;
memset(vis,,sizeof vis);
do{
ans+=w[pre[j]][j],j=pre[j],vis[j]=in[j]=;
}while(j!=i);
in[i]=;
for(int k=;k<=n;k++)
if(vis[k])
for(int j=;j<=n;j++)
if(!vis[j])
{
if(w[i][j]>w[k][j])w[i][j]=w[k][j];
if(w[j][k]<inf&&w[j][k]-w[pre[k]][k]<w[j][i])
w[j][i]=w[j][k]-w[pre[k]][k];
}
}
return ans;
}
int main()
{
/* ios::sync_with_stdio(false);
cin.tie(0);
cout<<setiosflags(ios::fixed)<<setprecision(2)<<endl;*/
while(~scanf("%d%d",&n,&m)){
for(int i=;i<=n;i++)
scanf("%lf%lf",&x[i],&y[i]);
for(int i=;i<=n;i++)
{
vis[i]=in[i]=;
for(int j=;j<=n;j++)
w[i][j]=inf;
}
while(m--){
int a,b;
scanf("%d%d",&a,&b);
if(a==b)continue;
w[a][b]=dis(a,b);
}
/* for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<w[i][j]<<" ";
cout<<endl;
}*/
double ans=dirmst();
if(ans<)printf("poor snoopy\n");
else printf("%.2f\n",ans);
}
return ;
}

最小树形图

poj3164最小树形图模板题的更多相关文章

  1. POJ 3164 Command Network(最小树形图模板题+详解)

    http://poj.org/problem?id=3164 题意: 求最小树形图. 思路: 套模板. 引用一下来自大神博客的讲解:http://www.cnblogs.com/acjiumeng/p ...

  2. uva11183 最小树形图模板题

    很简单的模板题,不多说了 #include<iostream> #include<cstring> #include<cstdio> #define INF 0x3 ...

  3. poj3164 最小树形图板子题

    /* 思路很简单,也不知道哪里错了TAT */ /* N个点通过笛卡尔坐标表示 根节点是1,求最小树形图 */ #include<iostream> #include<cstdio& ...

  4. hdu 4009 最小树形图模板题朱刘算法

    #include<stdio.h> /*思路:显然对于每个地方, 只有一种供水方式就足够了,这样也能保证花费最小, 而每个地方都可以自己挖井,所以是不可能出现无解的情况的, 为了方便思考, ...

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

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

  6. HDU 2121 Ice_cream’s world II 最小树形图 模板

    开始学习最小树形图,模板题. Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32 ...

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

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

  8. hdu4009最小树形图板子题

    /*调了一下午的最小树形图,昨天刚刚看懂模板..最小树形图,就是有向图的最小生成树,很神奇==*/ #include<iostream> #include<cstring> # ...

  9. poj 3164(最小树形图模板)

    题目链接:http://poj.org/problem?id=3164 详细可以看这里:http://www.cnblogs.com/vongang/archive/2012/07/18/259685 ...

随机推荐

  1. ScrollView 设置滚动是否可用

    extends:http://stackoverflow.com/questions/5763304/disable-scrollview-programmatically , http://stac ...

  2. 二叉树各种相关操作(建立二叉树、前序、中序、后序、求二叉树的深度、查找二叉树节点,层次遍历二叉树等)(C语言版)

    将二叉树相关的操作集中在一个实例里,有助于理解有关二叉树的相关操作: 1.定义树的结构体: typedef struct TreeNode{ int data; struct TreeNode *le ...

  3. 性能分析工具gprof介绍(转载)

    性能分析工具gprof介绍Ver:1.0 目录1. GPROF介绍 42. 使用步骤 43. 使用举例 43.1 测试环境 43.2 测试代码 43.3 数据分析 53.3.1 flat profil ...

  4. 170707、springboot编程之监控和管理生产环境

    spring-boot-actuator模块提供了一个监控和管理生产环境的模块,可以使用http.jmx.ssh.telnet等拉管理和监控应用.审计(Auditing). 健康(health).数据 ...

  5. T-SQL创建作业

    /*1.--创建作业 */ /*--调用示例 --每月执行的作业 exec p_createjob @jobname='mm',@sql='select * from syscolumns',@fre ...

  6. 无线路由器wan口和lan口ip同网段导致无法上网解决办法

    环境 本地网段为192.168.0.0/24 路由器默认网段也是192.168.0.0/24 设置好路由器wan口DHCP自动获取ip以后无法上网 解决办法 把路由器是lan口地址设置为192.168 ...

  7. P2750 贰五语言Two Five USACO5.5 记忆化搜索

    正解:记搜+逼近 解题报告: 神仙题预警,,, 我真滴觉得还是挺难的了,,, 大概说下思路趴QAQ 首先我们要知道逼近法是什么! 逼近法,有点像二分的思路,以这题为例举个eg 假如它给了个数字k.我们 ...

  8. python sort、sorted高级排序技巧(转)

    add by zhj: 没找到原文.可以按多个维度进行排序,而且可以指定他们的排序方向,如果维度都是数字,排序比较容易,用+/-号就可以 指定排序方向.否则,就调用多次sorted进行排序了,而且要按 ...

  9. HTTP返回码中301与302的区别(转)

    add by zhj:  区别 1.使用效果不同 302跳转是暂时的跳转,搜索引擎会抓取新的内容而保留旧的网址.因为服务器返回302代码,搜索引擎认为新的网址只是暂时的. 301重定向是永久的重定向, ...

  10. centos shell编程3【告警系统】 没有服务器端和客户端的概念 main.sh mon.conf load.sh 502.sh mail.php mail.sh disk.sh 第三十七节课

    centos shell编程3[告警系统]  没有服务器端和客户端的概念 main.sh mon.conf load.sh 502.sh mail.php mail.sh  disk.sh  第三十七 ...