HDU 2121 Ice_cream’s world II 不定根最小树形图
题目链接:
题目
Ice_cream’s world II
Time Limit: 3000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
问题描述
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.
输入
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.
输出
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.
样例
input
3 1
0 1 1
4 4
0 1 10
0 2 10
1 3 20
2 3 30
output
impossible
40 0
题意
不固定根最小树形图,并且多解时,输出根编号最小的解
题解
加一个虚根,与所有的点连接单向边,权值都为"所有边权和+1"。加这额外的n条边时,按顶点编号从小到大加。然后跑朱刘算法。
(为什么要所有权值+1呢?因为最后如果答案>=2*(所有边权和+1),就说明额外加的边用了不只一条,也就是根本无解的!)
代码
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 1111;
const int maxm = 20101;
const int INF = 0x7fffffff;
struct Edge {
int u, v, w;
Edge(int u,int v,int w):u(u),v(v),w(w){}
Edge() {}
}egs[maxm];
int N, M;
int pos;
int in[maxn],id[maxn], vis[maxn], pre[maxn];
int Directed_MST(int rt,int n,int m) {
int ret = 0;
while (1) {
//求最小入度边
for (int i = 0; i < n; i++) in[i] = INF;
for (int i = 0; i < m; i++) {
Edge& e = egs[i];
if (e.w < in[e.v] && e.u != e.v) {
//如果存在多解的话,那么那几个解一定在一个环上,因为以任意一个为根,都能到达其他点且使总权值最小。
//既然在环上最后就一定会缩成同一个点,虚根与它们的边就变成平行边了!由于我们额外的边是按节点编号从大到小排的,那么我们就只会记录编号最小的那个点了。
//这里不能记录pos=e.v,因为缩点之后e.v改变了
if (e.u == rt) pos = i; //这里rt就是须根了!!!缩点之后不会是N的!!!
in[e.v] = e.w;
pre[e.v] = e.u;
}
}
for (int i = 0; i < n; i++) {
if (i!=rt&&in[i] == INF) return -1;
}
int tot = 0;
memset(id, -1, sizeof(id));
memset(vis, -1, sizeof(vis));
in[rt] = 0;
//找环,缩点
for (int i = 0; i < n; i++) {
ret += in[i];
int v = i;
while (vis[v] != i&&id[v] == -1 && v != rt) {
vis[v] = i;
v = pre[v];
}
if (id[v] == -1 && v != rt) {
for (int u = pre[v]; u != v; u = pre[u]) {
id[u] = tot;
}
id[v] = tot++;
}
}
//没有环
if (tot == 0) break;
for (int i = 0; i < n; i++) {
if (id[i] == -1) id[i] = tot++;
}
//更新到环的距离
for (int i = 0; i < m; i++) {
Edge& e = egs[i];
int v = e.v;//这个v要留下来!
e.u = id[e.u],e.v = id[e.v];
if (e.u != e.v) {
e.w -= in[v];
}
}
n = tot;
rt = id[rt];
}
return ret;
}
int main() {
while (scanf("%d%d", &N, &M) == 2 && N) {
int sum = 0;
for (int i = 0; i < M; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
sum += w;
egs[i] = Edge(u, v, w);
}
sum++;
for (int i = 0; i < N; i++) {
egs[M + i] = Edge(N, i, sum);
}
int ans = Directed_MST(N, N + 1, N+M);
if (ans == -1 || ans >= sum * 2) {
puts("impossible");
}
else {
printf("%d %d\n", ans - sum, pos - M);
}
puts("");
}
return 0;
}
HDU 2121 Ice_cream’s world II 不定根最小树形图的更多相关文章
- 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/32 ...
- hdu 2121 Ice_cream’s world II (无定根最小树形图)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目大意: 有n个点,有m条单向路,问这n个点组成最小树形图的最小花费. 解题思路: 1:构造 ...
- HDU - 2121 Ice_cream’s world II 无根最小树形图
HDU - 2121 :http://acm.hdu.edu.cn/showproblem.php?pid=2121 比较好的朱刘算法blog:https://blog.csdn.net/txl199 ...
- HDU 2121 Ice_cream’s world II 最小树形图
这个题就是需要求整个有向带权图的最小树形图,没有指定根,那就需要加一个虚根 这个虚根到每个点的权值是总权值+1,然后就可以求了,如果求出来的权值大于等于二倍的总权值,就无解 有解的情况,还需要输出最根 ...
- hdu 2121 Ice_cream’s world II
Ice_cream’s world II http://acm.hdu.edu.cn/showproblem.php?pid=2121 Time Limit: 3000/1000 MS (Java/O ...
- Ice_cream’s world II(最小树形图,加虚点)
Ice_cream’s world II http://acm.hdu.edu.cn/showproblem.php?pid=2121 Time Limit: 3000/1000 MS (Java/O ...
- HDU2121 Ice_cream’s world II (最小树形图)
在建图的时候对原图进行加边 建立一个超级源点~ #include<cstdio> #include<algorithm> #include<cstring> usi ...
- hdoj 2121 Ice_cream’s world II 【没有最低树的根节点】
称号:pid=2121" target="_blank">hdoj 2121 Ice_cream's world II 题意:题目是一道躶题,给n个点,m条边的有向 ...
随机推荐
- 如何下载免费英特尔® 实感™ SDK
英特尔® 实感™ SDK支持的用途包括手/指跟踪.面部分析.语音识别和合成.背景分段.增强现实性等等,给你带来全新的人机交互体验.还不赶紧跟着我们一起免费下载英特尔® 实感™ SDK吧! 1. 输入网 ...
- Android webkit 事件传递流程详解
前言:基于android webview 上定制自己使用的可移植浏览器apk,遇到好多按键处理的问题.所以索性研究了一下keyevent 事件的传递流程. frameworks 层 keyevent ...
- ie、IE兼容模式,提示SCRIPT1028: 缺少标识符、字符串或数字
旧版ie下json最后一项是不允许有逗号的 为了更好的兼容各个浏览器,json最后的逗号最好不加
- JAVA:数组,排序,查找<4>
一.数组 1.一维数组 (1).数组的定义 数据类型 数组名[]=new 数据类型[大小] public class Demo1 { public static void main(String[] ...
- BigInteger大数家法源代码及分析
我们可以把一个很大很长的数分成多个短小的数,然后保存在一个数组中,大数之间的四则运算及其它运算都是通过数组完成.JDK就是这么实现的.JDK的BigInteger类里用一个int数组来保存数据: /* ...
- MySQL 备份和恢复
详细地址:http://imysql.cn/mysql_backup_and_recover
- Android四大组件之一:Activity
介绍:活动是最基本的Android组件之一,在应用程序中,一个活动通常就是一个用户界面,每一个活动都被实现为一个独立的类,并且从活动几类中继承, 活动类将会显示由View控件组成的用户接口,并对时间E ...
- DailyWallpaper - V1.01 released
桌面每日一图 最近发现美国国家地理网站上有个photo of the day很不错,地址在这里.http://photography.nationalgeographic.com/photograph ...
- c++11之右值引用
本文大部分来自这里,并不是完全着行翻译,如有不明白的地方请参考原文. 在c++中,创建临时对象的开销对程序的影响一直很大,比如以下这个例子: String getName(){ return “Kia ...
- Linux常用命令--文件的压缩和解压缩
在Linux系统中,我们通常使用的文件压缩命令有:bunzip2 , bzip2 , cpio , gunzip , gzip ,split(切割文件) , zgrep(在压缩文件中寻找匹配的正则表达 ...