链接: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. Solr搜索引擎 — 通过mysql配置数据源

    一,准备数据库数据表结构 CREATE TABLE `app` ( `id` int(11) NOT NULL AUTO_INCREMENT, `app_name` varchar(255) NOT ...

  2. Vue指令3:v-for

    列表渲染 我们用 v-for 指令根据一组数组的选项列表进行渲染.v-for 指令需要使用item in items 形式的特殊语法,items 是源数据数组并且 item 是数组元素迭代的别名. & ...

  3. CAD使用GetxDataDouble读数据(网页版)

    主要用到函数说明: MxDrawEntity::GetxDataDouble2 读取一个Double扩展数据,详细说明如下: 参数 说明 [in] LONG lItem 该值所在位置 [out, re ...

  4. CAD得到所有实体2

    主要用到函数说明: IMxDrawSelectionSet::Select2 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARI ...

  5. ThinkPHP---TP功能类之邮件

    [一]概论 (1)简介: 这里说的邮件不是平时说的email邮件(邮件地址带有@符号的),而是指的一般论坛网站的站内信息,也叫私信或者pm(private message私信) [二]站内信案例 (1 ...

  6. 08Microsoft SQL Server 数据查询

    Microsoft SQL Server 数据查询 单表查询所有列 --查询所有行所有列 select all * from table; --查询不重复行的所有列 select distinct * ...

  7. python的webservice请求

    1.pip install client 2.pip install suds-jurko #coding=utf-8from suds.client import Clientimport time ...

  8. fiddler培训

    fiddler  在客户端和服务器中间做一个代理 ,只能截获http或HTTPS的请求 代理地址127.0.0.1  端口8888 反向代理,正向代理 浏览器上设置代理地址和端口 左边是session ...

  9. 60.通过应用层join实现用户与博客的关联

    在构造数据模型的时候,将有关联关系的数据分割为不同的实体,类似于关系型数据库中的模型. 案例背景:博客网站,一个网站可能有多个用户,一个用户会发多篇博客,此时最好的方式是建立users和blogs两个 ...

  10. python爬虫28 | 你爬下的数据不分析一波可就亏了啊,使用python进行数据可视化

    通过这段时间 小帅b教你从抓包开始 到数据爬取 到数据解析 再到数据存储 相信你已经能抓取大部分你想爬取的网站数据了 恭喜恭喜 但是 数据抓取下来 要好好分析一波 最好的方式就是把数据进行可视化 这样 ...