【解题思路】这题先看了NotOnlySuccess的解题思路,即设置虚根再处理的做法;弄了一个上午,再次有种赶脚的感觉~~如果需要找出为什么需要去比所有权值之和更大的数为新增的虚边的话,一开始我理解仅是找比最大边权值要大的数就够了,因为这样就已经满足了不会提前找到虚边的情况,但如果是这样的话那就很难判断这样一种情况:生成的最小树形图(含虚根)有两条边是从虚根出来的。

 #include<cstdio>
#include<cstring>
#define SIZE 1002
#define MAXN 20004 using namespace std; const int INF = <<;
int nv, ne, aimroot;
int vis[SIZE], pre[SIZE], num[SIZE];
int inLength[SIZE]; struct Edge{
int u, v, w;
}edge[MAXN]; void addedge(int u, int v, int w)
{//添加虚根与原图中其他点相连的边
edge[ne].u = u;
edge[ne].v = v;
edge[ne].w = w;
return;
} bool Traverse(int& res, int root)
{
nv++;
while(true)
{
for(int i=; i<nv; ++i) inLength[i] = INF;
for(int i=; i<ne; ++i)
{
int& u = edge[i].u;
int& v = edge[i].v;
if(edge[i].w < inLength[v] && u != v)
{
//不管结点的Id号怎样变化,固定的边所在的位置是不会变的,根据边在edge数组中存储的位置与起初边的Id号的对应关系
//就能理解下面为什么要这样输出
if(u == root) aimroot = i;
inLength[v] = edge[i].w;
pre[v] = u;
}
}
for(int i=; i<nv; ++i)
if(i != root && inLength[i] == INF) return false;
int newnum = ;
inLength[root] = ;
memset(vis, -, sizeof(vis));
memset(num, -, sizeof(num));
for(int i=; i<nv; ++i)
{
res += inLength[i];
int v = i;
while(vis[v] != i && num[v] == - && v != root)
{
vis[v] = i;
v = pre[v];
}
if(vis[v] == i)
{
for(int u=pre[v]; u != v; u = pre[u])
num[u] = newnum;
num[v] = newnum++;
}
}
if(newnum == ) return true;
for(int i=; i<nv; ++i)
if(num[i] == -) num[i] = newnum++;
for(int i=; i<ne; ++i)
{
int u = edge[i].u;
int v = edge[i].v;
edge[i].u = num[u];
edge[i].v = num[v];
if(edge[i].u != edge[i].v)
edge[i].w -= inLength[v];
}
nv = newnum;
root = num[root];
} } int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
while(scanf("%d%d", &nv, &ne) != EOF)
{
int u, v, w, sum = ;
for(int i=; i<ne; ++i)
{
scanf("%d%d%d", &u, &v, &w);
edge[i].u = u;
edge[i].v = v;
edge[i].w = u == v ? INF+ : w;
sum += w;
}
sum++;
int temp = ne;
for(int i=; i<nv; ++i, ++ne)
addedge(nv, i, sum);
int res = ;
//res < 2*sum 设立这个条件是因为考虑到这种情况,虚根引出两条出边,这是不允许的,必须承认这是虚根,你得在原图中找到一个根
//这个条件成立了,说明有两条以上的虚边引出
if(Traverse(res, nv) && res < *sum)
//结合上面addedge函数中的说明,得到的aimroot存储的是你初始新存储虚边是在edge的下标,此下标大于或等于原图边的数目(边是从
//从零下标开始存储
printf("%d %d\n\n", res-sum, aimroot-temp);
else
printf("impossible\n\n");
}
return ;
}

HDU ACM 2121 Ice_cream’s world II (无根最小树形图)的更多相关文章

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

  2. hdu 2121 Ice_cream’s world II (无定根最小树形图)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2121 题目大意: 有n个点,有m条单向路,问这n个点组成最小树形图的最小花费. 解题思路: 1:构造 ...

  3. hdu 2121无根最小树形图要建一个虚拟节点

    #include<stdio.h> #include<string.h> #define inf 999999999 #define N 1100 struct node { ...

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

  5. hdoj 2121 Ice_cream’s world II 【没有最低树的根节点】

    称号:pid=2121" target="_blank">hdoj 2121 Ice_cream's world II 题意:题目是一道躶题,给n个点,m条边的有向 ...

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

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

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

  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 最小树形图

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

随机推荐

  1. HDU 1054:Strategic Game

    Strategic Game Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  2. POJ -3050 Hopscotch

    http://poj.org/problem?id=3050 给定一个5×5矩阵,问选6个数的不同排列总数是多少! 二维的搜索,注意要判重,数据量很小,直接用map就好. #include<cs ...

  3. 单元测试之道(使用NUnit)

    首先来看下面几个场景你是否熟悉 1.你正在开发一个系统,你不断地编码-编译-调试-编码-编译-调试……终于,你负责的功能模块从上到下全部完成且编译通过!你长出一口气,怀着激动而 又忐忑的心情点击界面上 ...

  4. VMware虚拟机中的常用文件介绍

    虚拟机的文件管理由VMware Workstation来执行.一个虚拟机一般以一系列文件的形式储存在宿主机中,这些文件一般在由workstation为虚拟机所创建的那个目录中. 如下图所示:(< ...

  5. .gitignore规则不生效的解决办法

    .gitignore规则不生效的解决办法 使用git 的时候,在.gitignore中已经添加了某个文件或者文件夹,但是使用git status还能看见该文件的修改提示--–说明.gitignore未 ...

  6. UVa 1609 (博弈) Foul Play

    姑且把它归类为一道博弈吧,毕竟这也是在找必胜方案. 十分有意思的一道题目,设计一种方案让你支持的1队获胜. 题目给出了两个很重要的条件: 1队能打败至少一半的队伍 对于1队不能打败的黑队,一定存在一个 ...

  7. Java Socket 模拟HTTP请求

    public static void main(String[] args) { try { String url = "192.168.1.103"; Socket socket ...

  8. BZOJ 1415 聪聪和可可

    f[i][j]表示i点追j点的期望步数... 这题必须spfa不能bfs. 且复杂度不会炸(仅1000条边) #include<iostream> #include<cstdio&g ...

  9. vim 常用命令总结

    https://www.ibm.com/developerworks/cn/linux/l-cn-tip-vim/ 1 文档开头末尾 [[ 开头 ]]末尾 2 删除全部 :%d 3 剪切.复制.粘贴 ...

  10. aspose.Cells 导出Excel

    aspose aspse.Cells可以操作Excel,且不依赖于系统环境. 使用模板,通过绑定输出数据源 这种适合于对格式没有特别要求的,直接绑定数据源即可.和数据绑定控件差不多. Workbook ...