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 ...
随机推荐
- 使用inline-box代替float
在网页布局中,使用float有不少好处,可以为你带来更加自由的布局,还可以自动根据浏览器改变布局效果.但是使用多了你也可能发现有一个问题,使用了float之后,外层的div不会撑高,导致布局出现坍塌. ...
- Jquery 1.6+ .prop()与.attr()方法比较
http://www.cnblogs.com/lujiahong/articles/2289867.html 今天在用JQuery的时候发现一个问题用.attr("checked" ...
- linux赋权限
给该文件夹赋权限命令 chmod u+x service-hcm-job.sh
- [Go]链表的相关知识
切片有着占用内存少喝创建便捷等特点,但它本质上还是数组.切片的一大好处是可以通过窗口快速地定位并获取或者修改底层数组中的元素.不过当删除切片中的元素的时候就没那么简单了.元素复制一般是免不了的,就算只 ...
- mapStruct笔记
背景 mapStruct 是一个方便对象转换的工具,类似的工具还有 Dozer, BeanUtils. 实现 mapStruct的核心是在编译期生成基于转换规则的 Impl 文件,运行时直接调用 Im ...
- HDU 3527 SPY
http://poj.org/problem?id=3615 基础题 狂STL #include <bits/stdc++.h> using namespace std; set<s ...
- 如何评价ionic和react native?
Q:对于开发hybird app首选哪个好?是ionic还是react native?如何评价ionic和react native? A: 我看好React系,React系以正确地姿势,专注地做了正确 ...
- 在jinja2的页面中使用javascript对页面元素进行删除
以对用户注册信息的审核为例. 后端的代码为: #encoding=utf-8 class RegisterCheck(system.page): '''注册信息审核''' path = "/ ...
- Wannafly模拟赛2 C alliances(dfs序+二分)
题目 https://www.nowcoder.com/acm/contest/4/C 题意 由n个点组成一个树,有m个帮派,每个帮派由一些个点组成,这些点以及它们两两路径上的所有点都属于该帮派的管辖 ...
- 数据库(Mysql)背后的数据结构-学习
来吧,用这三篇文章夯实对Mysql的理解吧. 关于数据库索引及其优化,更多可参见此文:http://www.cnblogs.com/pkuoliver/archive/2011/08/17/mass- ...