题目链接: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

Problem Description
After awarded lands to ACMers, the queen want to choose a city be her capital. This is an important event in ice_cream world, and it also a very difficult problem, because the world have N cities and M roads, every road was directed. Wiskey is a chief engineer in ice_cream world. The queen asked Wiskey must find a suitable location to establish the capital, beautify the roads which let capital can visit each city and the project’s cost as less as better. If Wiskey can’t fulfill the queen’s require, he will be punishing.
 
Input
Every case have two integers N and M (N<=1000, M<=10000), the cities numbered 0…N-1, following M lines, each line contain three integers S, T and C, meaning from S to T have a road will cost C.
 
Output
If no location satisfy the queen’s require, you must be output “impossible”, otherwise, print the minimum cost in this project and suitable city’s number. May be exist many suitable cities, choose the minimum number city. After every case print one blank.
 
Sample Input
3 1
0 1 1

4 4
0 1 10
0 2 10
1 3 20
2 3 30

 
Sample Output
impossible

40 0

 
Author
Wiskey
 
Source

题解:

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 —— 最小树形图 + 不定根 + 超级点的更多相关文章

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

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

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

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

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

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

  4. HDU4009 Transfer water —— 最小树形图 + 不定根 + 超级点

    题目链接:https://vjudge.net/problem/HDU-4009 Transfer water Time Limit: 5000/3000 MS (Java/Others)    Me ...

  5. hdu2121 Ice_cream's world II

    hdu2121 Ice_cream's world II 给一个有向图,求最小树形图,并输出根节点 \(n\leq10^3,\ m\leq10^4\) 最小树形图 对于求无根最小树形图,可以建一个虚拟 ...

  6. hdu2121 - Ice_cream’s world II(朱刘算法,不固定根)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目意思大概是要你在一些城市中选一个做首都 , 要求首都都能到其他城市 , 道路花费要最少 , ...

  7. HDU2121 Ice_cream’s world II (最小树形图)

    在建图的时候对原图进行加边 建立一个超级源点~ #include<cstdio> #include<algorithm> #include<cstring> usi ...

  8. HDU 2121——Ice_cream’s world II——————【最小树形图、不定根】

    Ice_cream’s world II Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

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

随机推荐

  1. 前端开发利器webStorm 3.0配置使用

     安装了phpstorm之后,想配置svn,结果在file->settings->Version Contorl->subversion->with conmand line ...

  2. python013 Python3 循环语句

    Python3 循环语句本章节将为大家介绍Python循环语句的使用.Python中的循环语句有 for 和 while.Python循环语句的控制结构图如下所示: while 循环Python中wh ...

  3. Codeforces Round #321 (Div. 2)-A. Kefa and First Steps,暴力水过~~

    A. Kefa and First Steps time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  4. 七牛云 GO 语言周报【七月第 2 期】

    全世界有多少 Gopher? 上周的周报中,我们介绍了 Go 语言的排名已经进入到前十.那么世界上到底有多少 Gopher 呢? 作者列出了以下计算公式: Gopher 数量 = 全世界的开发者数量 ...

  5. SGU515:Recover path 【最短路】

    警告:这题卡SPFA,警告:这题卡SPFA 这不是演习 题目大意:给出一个无向图,以及一些点的序列,要找出一条最短的路径使得通过所有点,题目保证存在一条头尾都在点的序列中的最短路满足题意 思路:没有最 ...

  6. 【贪心+二分】codeforces C. Sagheer and Nubian Market

    http://codeforces.com/contest/812/problem/C [题意] 如何花最少的钱买最多的纪念品?首要满足纪念品尽可能多,纪念品数量一样花钱要最少,输出纪念品数量以及最少 ...

  7. 【bzoj1042】[HAOI2008]硬币购物-递推与动规-容斥原理

    硬币购物 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一行 c1,c2 ...

  8. 【BZOJ1031】字符加密Cipher(后缀数组)

    题意:将一个长度为2n(复制粘贴后)的字符串的所有长度为n的后缀从小到大排序,并依次输出它们的最后一个字母. n<=100000 思路:裸SA,模板真难背 P党不得不写成C++风格 ..]of ...

  9. CODEVS5565 二叉苹果树

    n<=100个点的根为1的二叉树,树边上有苹果,求保留Q<=n条边的最多苹果数. 树形DP,f[i][j]--节点i为根的子树保留j条边最优方案,f[i][0]=0,f[i][j]=max ...

  10. 《effective C++》:条款36——绝不重新定义继承而来的非虚函数

    (1)当派生类中重写了基类的非虚函数时,这个时候这个函数发生的是静态绑定 下面中的代码中: 定义一个基类B,基类定义了函数fcm,fcm是非虚的函数. 定义一个派生类D,派生类重新定义了fcm. 当用 ...