hdu 6832 A Very Easy Graph Problem 构造树+dfs
题意:
给你一个n个点m条边的图,对于第i条边,它的长度是2i,对于每一个顶点,它不是0类型,就是1类型。你需要找出来对于所有的“两个不同类型的点之间最短距离”的和
题解(参考:https://blog.csdn.net/wayne_lee_lwc/article/details/107851431):
因为20+21+22<23,即20+21+...+2n-1<2n
所以如果第i条边连接的两个点已经联通,我们就不需要用这条边。所以这里用并查集判断下
后面我们用
sum,以该节点为根的子树中所有黑白点对的距离和
dp[0][0],子树中所有黑节点到该节点的距离和
dp[0][1],子树中黑节点的数量
dp[1][0],子树中所有白节点到该节点的距离和
dp[1][1],子树中白节点的数量
color,节点颜色
dfs先统计一下最小的子树上上面个变量的值,然后再上升到更大的子树上进行综合统计
代码+注释:
#include<stack>
#include<queue>
#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
using namespace std;
typedef long long ll;
const int N = 1e6 + 50;
const long long mod = 1e9 + 7;
struct Edge
{
ll point;
ll next;
long long w;
} nxt[N];
struct Node
{
ll type;
long long dp[2][2];
long long sum;
} node[N];
ll fa[N];
ll head[N];
ll T,n,m,tot;
ll finds(ll x)
{
if(x!=fa[x])
{
ll y=finds(fa[x]);
return fa[x]=y;
}
return x;
}
long long ppow(ll p)
{
long long ans = 1;
long long pow = 2;
while(p)
{
if(p & 1) ans = (ans * pow) % mod;
p >>= 1;
pow = (pow * pow) % mod;
}
return ans;
}
void add_edge(ll x,ll y,long long w)
{
nxt[++tot] = {y,head[x],w};
head[x] = tot;
}
/*
sum,以该节点为根的子树中所有黑白点对的距离和
dp[0][0],子树中所有黑节点到该节点的距离和
dp[0][1],子树中黑节点的数量
dp[1][0],子树中所有白节点到该节点的距离和
dp[1][1],子树中白节点的数量
color,节点颜色
*/
void dfs(ll k,ll f)
{
node[k].dp[node[k].type][1] = 1; for(ll i = head[k],j; i; i = nxt[i].next)
{
j = nxt[i].point;
if(j == f) continue;
dfs(j,k);
node[k].dp[0][0] = (node[k].dp[0][0] + node[j].dp[0][0] + (node[j].dp[0][1] * nxt[i].w) % mod) % mod;
node[k].dp[1][0] = (node[k].dp[1][0] + node[j].dp[1][0] + (node[j].dp[1][1] * nxt[i].w) % mod) % mod;
node[k].dp[0][1] += node[j].dp[0][1];
node[k].dp[1][1] += node[j].dp[1][1];
node[k].sum = (node[k].sum + node[j].sum) % mod;
}
long long sum0 = node[k].dp[0][0];
long long cnt0 = node[k].dp[0][1];
long long sum1 = node[k].dp[1][0];
long long cnt1 = node[k].dp[1][1];
long long w;
/*
比如k树下面有i,j两颗子树,那么i树上的白色点到j树上的黑色点的距离我们可以用:
i树上的白色点到k树的距离加上j树上黑色点到k树的距离
*/
for(ll i = head[k],j; i; i = nxt[i].next)
{
j = nxt[i].point;
if(j == f) continue;
w = nxt[i].w; //k树上的黑色节点数量,与子树j的白色节点,所有黑白队的距离和
node[k].sum = (node[k].sum + ((cnt0 - node[j].dp[0][1]) * (node[j].dp[1][0] + w * node[j].dp[1][1])) % mod) % mod;
//k树上的白色节点数量,与子树j的黑色节点,所有黑白队的距离和
node[k].sum = (node[k].sum + ((cnt1 - node[j].dp[1][1]) * (node[j].dp[0][0] + w * node[j].dp[0][1])) % mod) % mod;
}
}
int main()
{
cin >> T;
while(T--)
{
tot = 1;
scanf("%lld%lld",&n,&m);
for(ll i = 1; i <= n; i++)
{
node[i] = {0,0,0,0,0,0};
head[i] = 0;
scanf("%lld",&node[i].type);
fa[i] = i;
}
for(ll i = 1; i <= m; i++)
{
ll x,y;
scanf("%lld%lld",&x,&y);
//加了下面这个判断,那么1就肯定是我们构造的树的根节点
if(x>y) swap(x,y);
if(finds(x) == finds(y))
continue; add_edge(x,y,ppow(i));
add_edge(y,x,ppow(i));
fa[fa[y]] = fa[x];
}
dfs(1,0);
cout << node[1].sum << endl;
}
}
hdu 6832 A Very Easy Graph Problem 构造树+dfs的更多相关文章
- HDU 5572 An Easy Physics Problem (计算几何+对称点模板)
HDU 5572 An Easy Physics Problem (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5572 Descripti ...
- HDU 5572--An Easy Physics Problem(射线和圆的交点)
An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- hdu 5572 An Easy Physics Problem 圆+直线
An Easy Physics Problem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- HDU 5957 Query on a graph
HDU 5957 Query on a graph 2016ACM/ICPC亚洲区沈阳站 题意 \(N(N \le 10^5)\)个点,\(N\)条边的连通图. 有\(M \le 10^5\)操作: ...
- UVA11069 - A Graph Problem(DP)
UVA11069 - A Graph Problem(DP) 题目链接 题目大意:给你n个点.要你找出有多少子串符合要求.首先没有连续的数字,其次不能再往里面加入不论什么的数字而不违反第一条要求. 解 ...
- hdu 4972 A simple dynamic programming problem(高效)
pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...
- C#结合Jquery LigerUI Tree插件构造树
Jquery LigerUI Tree是Jquery LigerUI()的插件之一,使用它可以快速的构建树形菜单.呵呵 废话不说了,直入正题,下面介绍C#结合ligerui 构造树形菜单的两种方法 1 ...
- java 根据 根节点及所有子成员 构造树tree
实体类entity package com.ompa.biz.entity; import java.util.ArrayList; import java.util.List; public cla ...
- HDU 5692 线段树+dfs序
Snacks Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
随机推荐
- .net core 和 WPF 开发升讯威在线客服与营销系统:使用 WebSocket 实现访客端通信
本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程.本产品已经成熟稳定并投入商用. 在线演示环境:https://kf.shengxunwei.com 注意 ...
- linux中常用服务的安装
安装环境:centos7.5 配置离线yum源参考:https://blog.csdn.net/mayh554024289/article/details/54236336vi /etc/yum.co ...
- Win 10 Docker安装和简单使用
Win 10 Docker安装和简单使用 1.环境准备 Docker for Windows需要运行在64位Windows 10 Pro专业版.企业版或教育版(1607年纪念更新,版本14393或更高 ...
- 哈佛商学院MBA管理课程
课程示例:向上管理 课程 什么是向上管理? 了解自己和上司 建立合作关系 与上司进行有效沟通 管理糟糕的上司 向上管理课程内容: 全部课程目录 全部为离线文件(可有偿提供) 包括课程的全部内容,视频. ...
- 一文读懂 TKE 及 Kubernetes 访问权限控制
你有了解过Kubernetes的认证授权链路吗?是否对TKE的权限控制CAM策略.服务角色傻傻分不清楚?本文将会向你介绍腾讯云TKE平台侧的访问控制.Kubernetes访问控制链路,以及演示如何将平 ...
- 高效率同步降压变换器,24V转3.3V降压芯片
PW2312是一个高频,同步,整流,降压,开关模式转换器与内部功率MOSFET.它提供了一个非常紧凑的解决方案,以实现1.5A的峰值输出电流在广泛的输入电源范围内,具有良好的负载和线路调节. PW23 ...
- HTML部分
1.说一下<label>标签的用法 label标签主要是方便鼠标点击使用,扩大可点击的范围,增强用户操作体验 2.说一下事件代理? 事件委托是指将事件绑定到目标元素的父元素上,利用冒泡机制 ...
- python(re正则)
import re #导入模块 info = 'qwewwer12332423kdsjfkl2342kdjfl213nkafal123123' 例1: res1 = re.compile('er( ...
- apk开发环境!多亏这份《秋招+金九银十-腾讯面试题合集》跳槽薪资翻倍!再不刷题就晚了!
开头 最近很多网友反馈:自己从各处弄来的资料,过于杂乱.零散.碎片化,看得时候觉得挺有用的,但过个半天,啥都记不起来了.其实,这就是缺少系统化学习的后果. 为了提高大家的学习效率,帮大家能快速掌握An ...
- 【链表】leetcode-1290-二进制链表转整数
leetcode-1290-二进制链表转整数 题目描述 给你一个单链表的引用结点 head.链表中每个结点的值不是 0 就是 1.已知此链表是一个整数数字的二进制表示形式. 请你返回该链表所表示数字的 ...