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 (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5832 Accepted Submission(s): 1493
0 1 1
4 4
0 1 10
0 2 10
1 3 20
2 3 30
40 0
题解:
1.题目要求:给定一幅有向图,求最小树形图(根节点不确定)。
2.一开始想枚举每个结点作为根节点,然后跑zhuliu算法,求出最小值。结果发现复杂度太大。
3.可行做法:设置一个超级点,作为虚拟的根节点,把超级点连向每一个题目中的点。然后跑zhuliu算法,如果所得的最小树形图中只有一条超级边(超级点连向题目中的点,这个点就是实际的根节点),那么就求出实际了最小树形图;如果有多条超级边(实际得到的为最小树形图森林),则无解。
4.那么超级边的权值应该设为多少呢?由于我们需要从zhuliu算法返回的数据中判断出有多少条超级边,所以超级边就应该设置的足够大,以方便检测,但又不能溢出。所以我们将其设置为题目中所有边的权值之和+1。这样,只要zhuliu()返回来的数据:ans<2*super_edge,就表明只含有一条超级边,所以最终答案为ans-super_edge(减去人工设置的超级边)。否则,如果ans>=2*super_edge,则表明至少有两条超级边,也就说明了:在实际的图中(没有超级点),至少有两个结点是没有入边的。然而没有入边的结点只能有1个或者没有(作为根节点),所以无解。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = INT_MAX;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 1e3+; struct Edge
{
int u, v, w;
}edge[]; //super_edge为超级点连向每个普通点的边权, root_pos用于记录实际的根节点。
int super_edge, root_pos;
int pre[MAXN], id[MAXN], vis[MAXN], in[MAXN]; int zhuliu(int root, int n, int m)
{
int res = ;
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].w<in[edge[i].v])
{
pre[edge[i].v] = edge[i].u;
in[edge[i].v] = edge[i].w;
//为什么可以这样记录实际的根节点呢?因为在main()函数中,我们设置超级点连向普通点的时候,
//边的下标从m开始,对应着结点0, m+1对应着结点1,………所以我们可以根据边的下标得出边的终点。
if(edge[i].u==root)
root_pos = i; } for(int i = ; i<n; i++)
if(i!=root && in[i]==INF)
return -; int tn = ;
memset(id, -, sizeof(id));
memset(vis, -, sizeof(vis));
in[root] = ;
for(int i = ; i<n; i++)
{
res += in[i];
int v = i;
while(vis[v]!=i && id[v]==- && v!=root)
{
vis[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 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].w -= in[v];
}
n = tn;
root = id[root];
}
return res;
} int main()
{
int n, m;
while(scanf("%d%d", &n, &m)!=EOF)
{
super_edge = ;
for(int i = ; i<m; i++)
{
scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
super_edge += edge[i].w;
} super_edge++;
for(int i = ; i<n; i++) //n为超级点,将超级点连向每一个题目中的点
{
edge[m+i].u = n;
edge[m+i].v = i;
edge[m+i].w = super_edge;
} int ans = zhuliu(n, n+, m+n);
if(ans==- || ans>=*super_edge) printf("impossible\n\n");
else printf("%d %d\n\n", ans-super_edge, root_pos-m);
}
}
HDU2121 Ice_cream’s world II —— 最小树形图 + 不定根 + 超级点的更多相关文章
- hdu2121 Ice_cream’s world II 最小树形图(难)
这题比HDU4009要难一些.做了4009,大概知道了最小树形图的解法.拿到这题,最直接的想法是暴力.n个点试过去,每个都拿来做一次根.最后WA了,估计是超时了.(很多题都是TLE说成WA,用了G++ ...
- HDU 2121 Ice_cream’s world II 最小树形图 模板
开始学习最小树形图,模板题. Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
- HDU 2121 Ice_cream’s world II 最小树形图
这个题就是需要求整个有向带权图的最小树形图,没有指定根,那就需要加一个虚根 这个虚根到每个点的权值是总权值+1,然后就可以求了,如果求出来的权值大于等于二倍的总权值,就无解 有解的情况,还需要输出最根 ...
- HDU4009 Transfer water —— 最小树形图 + 不定根 + 超级点
题目链接:https://vjudge.net/problem/HDU-4009 Transfer water Time Limit: 5000/3000 MS (Java/Others) Me ...
- hdu2121 Ice_cream's world II
hdu2121 Ice_cream's world II 给一个有向图,求最小树形图,并输出根节点 \(n\leq10^3,\ m\leq10^4\) 最小树形图 对于求无根最小树形图,可以建一个虚拟 ...
- hdu2121 - Ice_cream’s world II(朱刘算法,不固定根)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目意思大概是要你在一些城市中选一个做首都 , 要求首都都能到其他城市 , 道路花费要最少 , ...
- HDU2121 Ice_cream’s world II (最小树形图)
在建图的时候对原图进行加边 建立一个超级源点~ #include<cstdio> #include<algorithm> #include<cstring> usi ...
- HDU 2121——Ice_cream’s world II——————【最小树形图、不定根】
Ice_cream’s world II Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...
- 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 ...
随机推荐
- Java面向对象重要关键字
面向对象过程接触的重要关键字:extends super this final static extends 关键字用作继承功能,可以申明一个类是从另外一个类继承而来的,一般形式如下 ...
- 图的最小生成树——Kruskal算法
Kruskal算法 图的最小生成树的算法之一,运用并查集思想来求出最小生成树. 基本思路就是把所有边从小到大排序,依次遍历这些边.如果这条边所连接的两个点在一个连通块里,遍历下一条边,如果不在,就把这 ...
- 七牛云 X 英语流利说:教育 3.0 时代的智能突破
美国当地时间 2018 年 9 月 27 日,国内领先的人工智能驱动的教育科技公司「英语流利说」正式挂牌纽交所,以其独创的教育 3.0 模式,成为中国「AI+ 教育」第一股. 教育 3.0 时代的智能 ...
- Codevs 二叉树遍历问题 合集
2010 求后序遍历 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 白银 Silver 题目描述 Description 输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列. ...
- secure上传图片
1.rz -bye 2.upload as ascii 去掉勾选框
- hdu6212 祖玛(区间DP)
题意 有一个长度为n的01串,我们可以在某个地方插入一个0或者1,那么如果有连续颜色相同的>=3个,那么这段就会消去,两边的合拢.问将所有01串消去,最少需要插入多少个.(n<=200) ...
- window环境下搭建SVN服务器
<span style="font-family: Arial; rgb(255, 255, 255);">第一步:准备工具:</span> 1.SVN服务 ...
- 【python】super()
转自: http://www.cnblogs.com/lovemo1314/archive/2011/05/03/2035005.html
- [转]三层架构与MVC之间的区别
我们平时总是将三层架构与MVC混为一谈,殊不知它俩并不是一个概念.下面我来为大家揭晓我所知道的一些真相. 首先,它俩根本不是一个概念. 三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目. ...
- JAVA_the user operation is waiting怎么办
彻底解决 MyEclipse出现the user operation is waiting的问题 2011-05-31 10:32:30| 分类: 软件编程 | 标签:java myecli ...