/*

最小树形图的第二题,终于有了一些理解

具体看注释

*/

/*
无定根的最小树形图
建立虚root
每次只找最短的那条入边
最小树形图理解:
第一步:寻找最短弧集E:扫一遍所有的边,找到每个点权值最小的入边,这一步会产生环
第二步:对每个点 i 找环:通过第一步记录的前驱找环,如果找到了原点或退到了另一个环,点i找环失败
第三步:缩点,缩点就是染色,把每个环内的点染上同一种颜色,每个环内点打上同一个id
第四步:更新一次边集:如果一条边连接两个不同颜色的点,就该边这条边的权值
重复以上四步。 最小树形图的root:root不需要入边
最小树形图的实质是最小生成树,所以用贪心的思想解决,但是贪心找入边时会生产环(第一步)
因此还得找另外一条边连到那个环中,才能解决这个环(第四步) 不定根确定根需要加一个虚根,由虚根为超级源点建立最小生成树,
这样由超级源点出发到达的第一个点就是实际最小生成树的根
虚根和每条边链接一条虚边,其权值要大于实根的和,以此判断是否连了两条虚边(建图失败) 如何找到那个实根:在不断形成环的过程中,会最先有一个点最先和虚根相连,这个点就是实根(实根是不需要入边的,但是在加了虚根后,实根不再是根)
贪心思想保证第一个和虚根链接的必定是实根
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#define ll long long
#define MAXN 1005
#define INF 0x3f3f3f
using namespace std;
struct Edge{
ll u,v,cost;
}edge[MAXN*MAXN];
ll pos;
int pre[MAXN],id[MAXN],visit[MAXN];
ll in[MAXN];
ll zhuliu(int root,int n,int m){
int res=;
int u,v;
while(){
for(int i=;i<n;i++)
in[i]=INF;
for(int i=;i<m;i++)
if(edge[i].u!=edge[i].v && edge[i].cost<in[edge[i].v]){
in[edge[i].v]=edge[i].cost;
pre[edge[i].v]=edge[i].u;
if(edge[i].u==root)
pos=i;
}
for(int i=;i<n;i++)
if(i!=root && in[i]==INF)
return -; int tn=;
memset(id,-,sizeof id);
memset(visit,-,sizeof visit);
in[root]=;
for(int i=;i<n;i++){
res+=in[i];
v=i;
while(visit[v]!=i && id[v]==- && v!=root){
visit[v]=i;
v=pre[v];
}
if(v!=root && id[v]==-){
for(int u=pre[v];u!=v;u=pre[u])
id[u]=tn;
id[v]=tn++;
}
} if(tn==)
break;//已经没有环了
for(int i=;i<n;i++)
if(id[i]==-)
id[i]=tn++; for(int i=;i<m;i++){//第四步,更新一次边集
int u=edge[i].u;
int v=edge[i].v;
edge[i].u=id[u];
edge[i].v=id[v];
if(id[u] != id[v])
edge[i].cost-=in[v];
}
n=tn;
root=id[root];
}
return res;
}
int main(){
ll n,m;
while(scanf("%lld%lld",&n,&m)==){
ll sum=;
for(ll i=;i<m;i++){ scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].cost);
edge[i].u++;edge[i].v++;
sum+=edge[i].cost;
} int root=n,tot=m;//加入虚根
for(ll i=m;i<n+m;i++){
edge[i].u=;
edge[i].v=i-m+;
edge[i].cost=sum+;
} ll ans=zhuliu(,n+,n+m);
if(ans==- || ans-(sum+)>=sum+)
printf("impossible\n\n");
else
printf("%lld %lld\n\n",ans-(sum+),pos-m);
}
return ;
}

hdu2121 最小树形图的虚根的更多相关文章

  1. hdu4966 最小树形图+虚根

    /* 辛辛苦苦调试半天, 过了样例,竟然没有ac!! 网上对比了ac代码,感觉添加一个虚根就能ac 但是想不明白为什么 */ /* 第二天想了下,知道了为什么wa:因为从等级0连到其他课程等级i的不止 ...

  2. hdu2121 Ice_cream’s world II 最小树形图(难)

    这题比HDU4009要难一些.做了4009,大概知道了最小树形图的解法.拿到这题,最直接的想法是暴力.n个点试过去,每个都拿来做一次根.最后WA了,估计是超时了.(很多题都是TLE说成WA,用了G++ ...

  3. hdu2121无定根的最小树形图

    无定根的最小树形图,像网络流的超级源和超级汇一样加一个起点,用邻接表(n>1000) n<1000用邻接矩阵 #include<map> #include<set> ...

  4. HDU2121 Ice_cream’s world II —— 最小树形图 + 不定根 + 超级点

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 Ice_cream’s world II Time Limit: 3000/1000 MS (J ...

  5. HDU ACM 2121 Ice_cream’s world II (无根最小树形图)

    [解题思路]这题先看了NotOnlySuccess的解题思路,即设置虚根再处理的做法:弄了一个上午,再次有种赶脚的感觉~~如果需要找出为什么需要去比所有权值之和更大的数为新增的虚边的话,一开始我理解仅 ...

  6. 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 ...

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

    这个题就是需要求整个有向带权图的最小树形图,没有指定根,那就需要加一个虚根 这个虚根到每个点的权值是总权值+1,然后就可以求了,如果求出来的权值大于等于二倍的总权值,就无解 有解的情况,还需要输出最根 ...

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

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

  9. hdu 2121 Ice_cream’s world II (无定根最小树形图)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目大意: 有n个点,有m条单向路,问这n个点组成最小树形图的最小花费. 解题思路: 1:构造 ...

随机推荐

  1. Flask网页模板的入门

    #网页模板需要导入render_template from flask import Flask,render_template   方法一: #使用render_template模块来渲染模板文件 ...

  2. java final、finally、finalize

  3. wait/notify实现线程间的通信

    使线程之间进行通信之后,系统间的交互性更加强大,在大大提高CPU利用率的同时还会使程序对各线程任务在处理的过程中进行有效的把控与监督. 1.不使用wait/notify实现线程间通信 使用sleep( ...

  4. 关于Oracle数据库后台进程

    为了最大限度地提高性能并适应许多用户,多进程Oracle数据库系统使用后台进程.后台进程将合并功能,否则这些功能将由运行于每个用户进程的多个数据库程序处理.后台进程异步执行I / O并监视其他Orac ...

  5. requests库入门07-patch请求

    使用data参数提交 设置邮件能见度,这个接口用来设置邮件是公共可见,还是私有的 import requests test_url = 'https://api.github.com' def get ...

  6. 检索每个字符串的子串(python散列表实现)

    import re def get_str(i,num): str_list = re.findall(r'.{{{str_length}}}'.format(str_length=i), num) ...

  7. WM_COMMAND消息

    原文地址:https://blog.csdn.net/whm243149796/article/details/78966065 当用户点击菜单.按钮.下拉列表框等控件时候,会触发WM_COMMAND ...

  8. Markdown中Latex 数学公式基本语法

    原文地址:http://blog.csdn.net/u014630987/article/details/70156489 Markdown中Latex 数学公式基本语法 公式排版 分为两种排版: - ...

  9. BZOJ3224/LOJ104 普通平衡树 pb_ds库自带红黑树

    您需要写一种数据结构,来维护一些数,其中需要提供以下操作:1. 插入x2. 删除x(若有多个相同的数,因只删除一个)3. 查询x的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. ...

  10. ionic之AngularJS——手势事件

    长按 : on-hold 在屏幕同一位置按住超过500ms,将触发on-hold事件: 你可以在任何元素上使用这个指令挂接监听函数: <any on-hold=“…”>…</any& ...