链接: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. Windows下80端口被进程System&PID=4占用的解决方法

    我的占用原因是 SQL Server Reporting Services,停止掉这个服务并设置其为手动启动即可 如果你并没有安装 SQL Server,请参考下文解决 =============== ...

  2. 【Python-2.7】删除空格

    有时我们在编程过程中,需要去除字符串两边的空格,可以用如下函数解决问题: rstrip():去除字符串右边的空格: lstrip():去除字符串左边的空格: strip():去除字符串两边的空格. 示 ...

  3. Codeforces_761_E_(dfs)

    E. Dasha and Puzzle time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  4. 巧用TWaver 3D 矢量图形功能

    的确,提起TWaver,大家想到的首先是“电信拓扑图组件”.其实,由于其灵活的MVC架构.矢量化设计.方便定制等特点,TWaver可以做的还有很多.例如房地产行业常见到的“户型图”. 户型推荐是销售接 ...

  5. [Luogu] P4366 [Code+#4]最短路

    题目背景 在北纬 91° ,有一个神奇的国度,叫做企鹅国.这里的企鹅也有自己发达的文明,称为企鹅文明.因为企鹅只有黑白两种颜色,所以他们的数学也是以二进制为基础发展的. 比如早在 1110100111 ...

  6. fiddler培训

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

  7. buf.writeFloatBE()函数详解

    buf.writeFloatBE(value, offset[, noAssert]) buf.writeFloatLE(value, offset[, noAssert]) value {Numbe ...

  8. mac下用crontab实现pytho3脚本自动定期执行,包括scrapy的定期执行

    呃 其实要明天上午才能知道是否成功,毕竟改了一个小参数的. 首先,来学两个小命令: step1: $ sudo crontab -e step2: # 然后提示password输入密码,即可进入编辑页 ...

  9. 《编译原理》构造 LL(1) 分析表的步骤 - 例题解析

    <编译原理>构造 LL(1) 分析表的步骤 - 例题解析 易错点及扩展: 1.求每个产生式的 SELECT 集 2.注意区分是对谁 FIRST 集 FOLLOW 集 3.开始符号的 FOL ...

  10. HDU 1176 DP

    题目大意: 在0~10这11个点上面接饼 , 每秒最多往左或往移动一格,或者保持原地不动 令dp[i][j]表示在第 i 秒在 第 j 个点上最多能得到的饼的数量 dp[i][j] = max(dp[ ...