HDU2121:Ice_cream’s world II (虚根+有向图最小生成树)
Ice_cream’s world II
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6849 Accepted Submission(s): 1818
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121
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
题意:
给出一个有向图,然后让你选一个点作为起点,满足从这个点可以到达其它点,并且总权和最小。
题解:
这就是一个不固定根的有向图最小生成树问题。思路还是挺有趣的。
我们不可能对每个点都跑一遍朱刘算法,所以考虑加一个虚根,然后边权为INF,直接从这个虚根来跑就行了。最后答案就是跑出来的值减去INF。
但是这里要注意的是一些不合法的情况,就是最后的答案大于2*INF时,因为这时,说明至少有两个点入度为0,那么说明不可能存在一颗有向图的生成树。
至于这个INF怎么取,只要满足大于等于边权和就行了(我是这么想的),不知道为什么不能等于,这个问题我纠结了很久,就在刚才知道为什么了。。
可能存在只有一条边的情况,这时如果连边权和,这时算法可能会出错。
最后输出起点,这里比较巧妙,是根据边来的,因为我们会改变点(算法缩点),但边并没有改变,具体见代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
#define INF 1e17
using namespace std;
typedef long long ll;
int n,m,t;
const int N = ,M = ;
struct Edge{
int u,v,w;
}e[M<<];
int pre[N]; //记录前驱
int Rt;
ll id[N],vis[N],in[N];
ll dirMst(int root){
ll ans=;
while(){
for(int i=;i<=n;i++) in[i]=INF;
memset(id,-,sizeof(id));
memset(vis,-,sizeof(vis));
for(int i=;i<=m;i++){
int u=e[i].u,v=e[i].v,w=e[i].w;
if(w<in[v] && v!=u){
pre[v]=u;
in[v]=w;
if(u==root) Rt=i;
}
} //求最小入边集
in[root]=;
pre[root]=root;
for(int i=;i<n;i++){
if(in[i]==INF) return -;
ans+=in[i];
}
int idx = ; //新标号
for(int i=;i<n;i++){
if(vis[i] == - ){
int u = i;
while(vis[u] == -){
vis[u] = i;
u = pre[u];
}
if(vis[u]!=i || u==root) continue; //判断是否形成环
for(int v=pre[u];v!=u;v=pre[v] )
id[v]=idx;
id[u] = idx++;
}
}
if(idx==) break;
for(int i=;i<n;i++){
if(id[i]==-) id[i]=idx++;
}
for(int i=;i<=m;i++){
e[i].w-=in[e[i].v];
e[i].u=id[e[i].u];
e[i].v=id[e[i].v];
}
n = idx;
root = id[root];//给根新的标号
}
return ans;
} int main(){
while(scanf("%d%d",&n,&m)!=EOF){
ll sum = ;
for(int i=;i<=m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
e[i]=Edge{u,v,w};
sum+=w;
}
sum++;
for(int i=;i<n;i++){
e[i+m+]=Edge{n,i,sum};
}
ll tmp=m;
m+=n;n++;
ll ans = dirMst(n-);
if(ans>*sum) printf("impossible\n\n");
else printf("%lld %lld\n\n",ans-sum,Rt-tmp-1ll);
}
}
HDU2121:Ice_cream’s world II (虚根+有向图最小生成树)的更多相关文章
- 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 Ice_cream’s world II Time Limit: 3000/1000 MS (J ...
- hdu2121 - Ice_cream’s world II(朱刘算法,不固定根)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目意思大概是要你在一些城市中选一个做首都 , 要求首都都能到其他城市 , 道路花费要最少 , ...
- hdu2121 Ice_cream’s world II 最小树形图(难)
这题比HDU4009要难一些.做了4009,大概知道了最小树形图的解法.拿到这题,最直接的想法是暴力.n个点试过去,每个都拿来做一次根.最后WA了,估计是超时了.(很多题都是TLE说成WA,用了G++ ...
- 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: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- hdoj 2121 Ice_cream’s world II 【没有最低树的根节点】
称号:pid=2121" target="_blank">hdoj 2121 Ice_cream's world II 题意:题目是一道躶题,给n个点,m条边的有向 ...
- HDU 2121 Ice_cream’s world II 最小树形图 模板
开始学习最小树形图,模板题. Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
- Uva11183-Teen Girl Squad(有向图最小生成树朱刘算法)
解析: 裸的有向图最小生成树 代码 #include<cstdio> #include<cstring> #include<string> #include< ...
随机推荐
- Click Once使用总结
做了一个CS结构软件,有十几个用户使用的客户端,因为刚开始试用期间,要不断根据用户使用情况修正问题和添加新功能,所以频繁更新是不可避免的,暂时没有深入去研究软件更新,暂时采取的方式是用户通过FTP自行 ...
- 【Python 开发】第二篇 :Python安装
一.python3.x安装 1)由于centos7原本就安装了Python2,而且这个Python2不能被删除,因为有很多系统命令,比如yum都要用到. 官网:https://www.python.o ...
- 关于excle导数据的一些代码笔记
package com.bonc.util; import java.io.File; import java.io.FileInputStream; import java.io.FileOutpu ...
- docker创建redis镜像
pull redis 镜像 创建redis的镜像有几种方式,可以直接从仓库中拉取,也可以采用dockerfile文件自己编译创建. 基于已有的redis镜像,docker可以采用run,或者creat ...
- CVPR-2018 那些有趣的新想法
Taylor Guo @ Shanghai - 2018.10.18 缘起 还有什么比顶级会议更适合寻找有趣新想法的地方吗?我们从CVPR 2018 计算机视觉和模式识别的顶级会议中发现了很多有趣的东 ...
- Caching Data in the Architecture (C#)
http://www.asp.net/web-forms/tutorials/data-access/caching-data/caching-data-in-the-architecture-cs ...
- Calculator Part Ⅰ (代码规范化修改)
GitHub/object-oriented 本次参照的C++代码规范 有一些规范内容在文件中其实并未提及,比如:空格的使用,修改的时候真的是一头雾水--根据文件中的例子,发现了一些文字部分没有提到的 ...
- ACM 第十八天
数学基础(卷积,FFT,FWT,FMT,鸽巢原理,群论,哈里亚余数,哈里亚计数定理,组合数学,LVG定理,期望DP,期望点贡献问题) 练习题: A - Necklace of Beads Beads ...
- 透过汇编另眼看世界之DLL导出函数调用
前言:我一直对DLL技术充满好奇,一方面是因为我对DLL的导入/导出机制还不是特别的了解,另一面是因为我发现:DLL技术在Windows平台下占有重要的地位,几乎所有的Win32 API都是以导出函数 ...
- TCP系列40—拥塞控制—3、慢启动和拥塞避免概述
本篇中先介绍一下慢启动和拥塞避免的大概过程,下一篇中将会给出多个linux下reno拥塞控制算法的wireshark示例,并详细解释慢启动和拥塞避免的过程. 一.慢启动(slow start) 一个T ...