链接:http://acm.hdu.edu.cn/showproblem.php?

pid=2121

题意:n个顶点,m条边,求从某一点起建立有向图最小生成树而且花费最小。输出最小花费和根节点下标。

思路:这道题根是不确定的,我们能够先如果一个根。从这个根出发到不论什么一点的距离(sum)都比原图总权值还大。这样保证了虚拟的边不会是最小入边,也为之后推断是否生成了最小树形图提供方便,从这个点開始建立最小树形图,最后生成出一个结果。非常显然虚拟的根仅仅有一条出边。而且出边连接的点就是真实的根。

最后得到的最小树形图权值,减去虚拟边的权值sum。假设结果大于等于sum,说明虚拟顶点的出边不止一条,也即假设不靠这个虚拟顶点原图无法构成最小树形图,这是最小树形图的还有一个推断条件。

至于真实的根,找到某点的最小入边,假设出边的点是虚拟根,则这个点就是真实根,可是我们不能直接记录这个顶点。由于这个顶点可能是缩点后的点,所以我们记录边的编号,由于虚拟边的编号是从m開始添加n条边的。最后用记录的边的编号减去m就是真实根的下标。

/*
最小树形图图模版-朱刘算法
模版说明:点标号必须0-(N-1)
必须去除到自身的点(到自身的边的边权赋无限大)
*/
#include<cstring>
#include<string>
#include<fstream>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cctype>
#include<algorithm>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<ctime>
#include<cstdlib>
#include<functional>
#include<cmath>
using namespace std;
#define PI acos(-1.0)
#define MAXN 50100
#define eps 1e-7
#define INF 0x7FFFFFFF
#define seed 131
#define mod 1000000007
#define ll long long
#define ull unsigned ll
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 struct node{
int u,v;
int dis;
}edge[20100];
int pre[1010],ID[1010],vis[1010];
int n,m;
int In[1010];
int ansp;
int Directed_MST(int root,int NV,int NE) {
int ret = 0;
while(true) {
//1.找最小入边
for(int i=0;i<NV;i++) In[i] = INF;
for(int i=0;i<NE;i++){
int u = edge[i].u;
int v = edge[i].v;
if(edge[i].dis < In[v] && u != v) {
pre[v] = u;
In[v] = edge[i].dis;
if(u==root) ansp = i; //实际上应该等于v。可是v有可能是缩点,所以等于i。之后再减去m就是顶点编号
}
}
for(int i=0;i<NV;i++) {
if(i == root) continue;
if(In[i] == INF) return -1;//除了根以外有点没有入边,则根无法到达它
}
//2.找环
int cntnode = 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];
}
if(v != root && ID[v] == -1) {
for(int u = pre[v] ; u != v ; u = pre[u]) {
ID[u] = cntnode;
}
ID[v] = cntnode ++;
}
}
if(cntnode == 0) break;//无环
for(int i=0;i<NV;i++) if(ID[i] == -1) {
ID[i] = cntnode ++;
}
//3.缩点,又一次标记
for(int i=0;i<NE;i++) {
int v = edge[i].v;
edge[i].u = ID[edge[i].u];
edge[i].v = ID[edge[i].v];
if(edge[i].u != edge[i].v) {
edge[i].dis -= In[v];
}
}
NV = cntnode;
root = ID[root];
}
return ret;
}
int main(){
int i,j,a,b,c;
double temp;
while(scanf("%d%d",&n,&m)!=EOF){
int x = m;
int sum = 0;
for(i=0;i<m;i++){
scanf("%d%d%d",&a,&b,&c);
edge[i].u = a + 1;
edge[i].v = b + 1;
edge[i].dis = c;
sum += c;
}
sum++;
for(i=m;i<m+n;i++){
edge[i].u = 0;
edge[i].v = i - m + 1;
edge[i].dis = sum;
}
int ans = Directed_MST(0,n+1,m+n);
if(ans==-1||ans-sum>=sum) puts("impossible");
else printf("%d %d\n",ans-sum,ansp-x);
puts("");
}
return 0;
}

HDUOJ--2121--Ice_cream’s world II【朱刘算法】不定根最小树形图的更多相关文章

  1. hdu2121 - Ice_cream’s world II(朱刘算法,不固定根)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目意思大概是要你在一些城市中选一个做首都 , 要求首都都能到其他城市 , 道路花费要最少 , ...

  2. POJ--3164--Command Network【朱刘算法】最小树形图

    链接:http://poj.org/problem?id=3164 题意:告诉n个点坐标,m条边表示两个点之间有路.从1点開始建立一个有向图最小生成树. 朱刘算法模板题 =============== ...

  3. uva11865 朱刘算法+二分

    这题说的需要最多花费cost元来搭建一个比赛网络,网络中有n台机器,编号为0 - n-1其中机器0 为服务器,给了n条线有向的和他们的花费以及带宽 计算,使得n台连接在一起,最大化网络中的最小带宽, ...

  4. HDU 2121——Ice_cream’s world II——————【最小树形图、不定根】

    Ice_cream’s world II Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  5. HDU 2121 Ice_cream’s world II 不定根最小树形图

    题目链接: 题目 Ice_cream's world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...

  6. hdoj 2121 Ice_cream’s world II 【没有最低树的根节点】

    称号:pid=2121" target="_blank">hdoj 2121 Ice_cream's world II 题意:题目是一道躶题,给n个点,m条边的有向 ...

  7. HDU - 2121 Ice_cream’s world II 无根最小树形图

    HDU - 2121 :http://acm.hdu.edu.cn/showproblem.php?pid=2121 比较好的朱刘算法blog:https://blog.csdn.net/txl199 ...

  8. UVA 11865 Stream My Contest 组网 (朱刘算法,有向生成树,树形图)

    题意: 给n个点编号为0~n-1,0号点为根,给m条边(含自环,重边),每条边有个代价,也有带宽.给定c,问代价不超过c,树形图的最小带宽的最大值能达到多少? 思路: 点数才60,而带宽范围也不大,可 ...

  9. UVa11183 Teen Girl Squad, 最小树形图,朱刘算法

    Teen Girl Squad  Input: Standard Input Output: Standard Output You are part of a group of n teenage ...

随机推荐

  1. Zynq7000系列之芯片引脚功能综述

    很多人做了很久的FPGA,知道怎么去给信号分配引脚,却对这些引脚的功能及其资源限制知之甚少:在第一章里对Zynq7000系列的系统框架进行了分析和论述,对Zynq7000系列的基本资源和概念有了大致的 ...

  2. Ps 快捷键全解

    一.工具箱(多种工具共用一个快捷键的可同时按[Shift]加此快捷键选取)矩形.椭圆选框工具 [M]移动工具 [V]套索.多边形套索.磁性套索 [L]魔棒工具 [W]裁剪工具 [C]切片工具.切片选择 ...

  3. Verilog之event

    1 Explicit event The value changes on nets and variable can be used as events to trigger the executi ...

  4. python学习笔记(6)——for...in &while

    for x in ...循环就是把每个元素代入变量x,然后执行缩进块的语句. 注意:python中的格式也起到语法规则的作用,缩进块就是一个例 求和问题,比较异同 1/sum= ,,,,,,,,,]: ...

  5. 服务器主机&软件性能测试自定标准

    PS:最近一直致力于代理ip的服务搭建,其中就要根据客户群体的不同来测试搭建环境和搭建软件的性能,但是不同的客户群体所处的环境和使用的软件是不同的,而业内又没有一套完整的评估方法.在忽略网络本身来讲, ...

  6. map 用法

    map 是一种关联容器,  提供一对一的关联, 关联的形式为: KEY----VALUE     关键字不重复.multimap与map类似,但是允许关键字重复 即:关键字和与之对应的值 关键字起到索 ...

  7. vue组件---组件注册

    (1)组件名 在注册一个组件的时候,我们始终需要给它一个名字.比如在全局注册的时候我们已经看到了: Vue.component('my-component-name', { /* ... */ }) ...

  8. xmpp获取好友信息和添加删除好友(4)

    原始地址: XMPPFrameWork IOS 开发(五)获取好友信息和添加删除好友 好友列表和好友名片 [_xmppRoster fetchRoster];//获取好友列表 //获取到一个好友节点 ...

  9. 行内块+calc+margin 三列布局

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  10. JavaScript--小白入门篇1

    一.JavaScript简介 1.1 JavaScript的用途   JavaScript用来制作web页面交互效果,提升用户体验.    简单列出几个JavaScript能够制作的页面效果,它能干什 ...