hdu 6141 I am your Father!
题
OvO http://acm.hdu.edu.cn/showproblem.php?pid=6141
(2017 Multi-University Training Contest - Team 8 - 1009)
解
首先这是一个有向图,所以使用最小树形图算法。
然后题目要求的是节点n的父亲节点的值最小,
那么,可以把全部边的值乘以1000,如果这条边的终止点是节点n的话,设这条边的起始点为u,那么边值加上(999-u),这样就能保证优先取字典序小的,
然后由于题目要求的是最大的,所以可以把边的值取倒数。
至于最小树形图算法,
1. 找当前图每个节点的非自环最小入边,
2. 如果当天图存在环:把环缩成点,然后构造一张新图,返回步骤1,(至于如何构造,见下图)
否则结束
这张图我复制的(我感觉这张图超好懂来着),来源:O∧O (貌似来源处这张图也是复制的)

(思路来自题解)
#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1005
#define INF 0x7f7f7f7f
using namespace std;
typedef long long ll;
struct node
{
int u, v;
ll w;
}edge[MAXN * MAXN];
int pre[MAXN], id[MAXN], vis[MAXN], n, m, pos;
int ans_father;
ll in[MAXN];
ll Directed_MST(int root, int V, int E) //边、点全是从0开始计算的
{
ll ret = 0;//存最小树形图总权值
while(true)
{
int i;
//1.找每个节点的最小入边
for( i = 0; i < V; i++)
in[i] = INF;//初始化为无穷大
for( i = 0; i < E; i++)//遍历每条边
{
int u = edge[i].u;
int v = edge[i].v;
if(edge[i].w < in[v] && u != v)//说明顶点v有条权值较小的入边 记录之
{
pre[v] = u;//节点u指向v
in[v] = edge[i].w;//最小入边
if(u == root)//这个点就是实际的起点
pos = i;
}
}
for( i = 0; i < V; i++)//判断是否存在最小树形图
{
if(i == root)
continue;
if(in[i] == INF)
return -1;//除了根以外有点没有入边,则根无法到达它 说明它是独立的点 一定不能构成树形图
}
//2.找环
int cnt = 0;//记录环数
memset(id, -1, sizeof(id));
memset(vis, -1, sizeof(vis));
in[root] = 0;
for( i = 0; i < V; i++) //标记每个环
{
ret += in[i];//记录权值
int v = i;
while(vis[v] != i && id[v] == -1 && v != root)
{
vis[v] = i;
v = pre[v];
}
if(v != root && id[v] == -1)
{
for(int u = pre[v]; u != v; u = pre[u])
id[u] = cnt;//标记节点u为第几个环
id[v] = cnt++;
}
}
if(cnt == 0)
break; //无环 则break
for( i = 0; i < V; i++)
if(id[i] == -1)
id[i] = cnt++;
//3.建立新图 缩点,重新标记
for( i = 0; i < E; i++)
{
int u = edge[i].u;
int v = edge[i].v;
edge[i].u = id[u];
edge[i].v = id[v];
if(id[u] != id[v])
edge[i].w -= in[v];
}
V = cnt;
root = id[root];
}
return ret;
}
int main()
{
// freopen("数据\\1009.in","r",stdin);
// freopen("数据\\fxxl1009.out","w",stdout);
int i,j,cas;
scanf("%d",&cas);
while(cas--)
{
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
{
scanf("%d%d%lld", &edge[i].u, &edge[i].v, &edge[i].w);
edge[i].u--; edge[i].v--;
edge[i].w*=1000;
if(edge[i].v==n-1)
edge[i].w+=(999-edge[i].u);
edge[i].w*=-1;
}
ll ans = Directed_MST(0,n,m);
// cout<<ans<<' '<<ans_father<<endl;
ans*=-1;
ans_father=(999-ans%1000)+1;
ans=ans/1000;
printf("%lld %d\n",ans,ans_father);
}
return 0;
} /* 1
3 8
1 2 10
2 1 10
2 3 10
3 2 10
1 3 10
3 1 10
2 1 100
3 1 100 */
hdu 6141 I am your Father!的更多相关文章
- HDU 6141 - I am your Father! | 2017 Multi-University Training Contest 8
思路来自 FXXL 最小树形图模板用kuangbin的 /* HDU 6141 - I am your Father! [ 最小树形图 ] | 2017 Multi-University Traini ...
- HDU 6141 I am your Father!(最小树形图+权值编码)
http://acm.hdu.edu.cn/showproblem.php?pid=6141 题意: 求最大树形图. 思路: 把边的权值变为负值,那么这就是个最小树形图了,直接套模板就可以解决. 有个 ...
- HDU 6141 I am your Father!(最小树形图)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6141 [题目大意] 给出一个有向图,求1点为根的最小树形图使得第n个点的直接父亲编号最小 [题解] ...
- hdu 1178 Heritage from father (推导)
题意: 有一个金币堆的金字塔,最上层就有一个金币,以后的i层都是边长为i的实心三角形,给你层数,问:一共有多少个金币?(用科学计数法表示,并且保留两位小数) 解题思路: 根据题意可知求出1*n+2*( ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 2376 树形dp|树上任意两点距离和的平均值
原题:http://acm.hdu.edu.cn/showproblem.php?pid=2376 经典问题,求的是树上任意两点和的平均值. 这里我们不能枚举点,这样n^2的复杂度.我们可以枚举每一条 ...
- HDU 4757 Tree(可持久化Trie+Tarjan离线LCA)
Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total Su ...
- hdu 4035 2011成都赛区网络赛E 概率dp ****
太吊了,反正我不会 /* HDU 4035 dp求期望的题. 题意: 有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 从结点1出发,开始走,在每个结点i都有3种可能: 1.被杀死,回到结点 ...
- HDU 1102 最小生成树裸题,kruskal,prim
1.HDU 1102 Constructing Roads 最小生成树 2.总结: 题意:修路,裸题 (1)kruskal //kruskal #include<iostream> ...
随机推荐
- AndroidStudio布局编辑器强制刷新布局界面
用AndroidStudio布局编辑器编辑界面的时候,在selector里调整按钮的颜色,调整后的颜色经常无法实时显示在布局编辑器里,每次都重新运行程序查看界面又非常麻烦和低效,可以用以下方法解决: ...
- php静态调用非静态方法
<?php /** * php静态调用非静态方法 * author: 百里 * Date: 2019/7/18 * Time: 17:28 */ function dump(...$var) { ...
- selenium弹框元素定位-冻结界面
有些网站上面的元素,我们鼠标放在上面,会动态弹出一些内容. 比如,百度首页的右上角,有个更多产品选项,如下图所示: 如果我们把鼠标放在上边,就会弹出下面的百度营销.音乐.图片等图标. 如果我们要用se ...
- CDN内容分发
什么是CDN内容分发: CDN的全称是Content Delivery Network,即内容分发网络.CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡.内容分 ...
- 补充第11期作业:Long.fastUUID与UUID.toString之间的关系
一 UUID.toString方法与Long.fastUUID方法的关联 UUID类 public final class UUID implements java.io.Serializable, ...
- MyEclipse10.0 采用插件方式安装 SVN
一.到官方上下载svn1.8.3,下载后的文件名叫site-1.8.3.zip 地址:http://subclipse.tigris.org/servlets/ProjectDocumentList? ...
- $.proxy的使用
$.proxy()是jquery的一个方法.是一个改变this指向的方法. 在某些情况下,我们调用Javascript函数时候,this指针并不一定是我们所期望的那个.例如: //正常的this使用 ...
- php实现多进程、多线程
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作. 僵尸进程:一个进程使用f ...
- php 限制标题长度,将一个中文转换成一个字符
点击链接加入群[php/web 学习课堂]:https://jq.qq.com/?_wv=1027&k=5UJ9vEa 欢迎大家加入,一起讨论学习 玩这个功能的时候,我们要注意一点,我们是用中 ...
- 不重启linuxVMWare虚拟机添加虚拟光驱、硬盘
方法/步骤1: VMware找到要添加虚拟光驱位置,先右击点击设置,如图所示: 步骤2: 出现此界面之后点击添加: 步骤3: 直接点击下一步,如下图所示: 点击完成,天机硬盘就完毕了. 磁盘添加完成, ...