描述

在古老的皇宫中,有N个房间以及N-1条双向通道,每条通道连接着两个不同的房间,所有的房间都能互相到达。皇宫中有许多的宝物,所以需要若干个大内密探来守护。一个房间被守护当切仅当该房间内有一名大内密探或者与该房间直接相邻的房间内有大内密探。

现在身为大内密探零零七的你想知道要把整个皇宫守护好至少需要多少名大内密探以及有多少种安排密探的方案。两种方案不同当且仅当某个房间在一种方案有密探而在另一个方案内没有密探。

格式

输入格式

第一行一个正整数N.(1<=N<=100000)
后面N-1行,每行两个正整数a和b,表示房间a和房间b之间有一条无向通道。

房间的编号从1到N

输出格式

第一行输出正整数K,表示最少安排的大内密探。

第二行输出整数S,表示有多少种方案安排最少的密探,由于结果可能较大,请输出方案数mod 1000000007的余数。

样例1

样例输入1[复制]
7
2 1
3 1
4 2
5 1
6 2
7 6
样例输出1[复制]
3
4
 
#include<map>
#include<stack>
#include<queue>
#include<cstdio>
#include<string>
#include<vector>
#include<cstring>
#include<complex>
#include<iostream>
#include<assert.h>
#include<algorithm>
using namespace std;
using namespace std;
#define pb push_back
#define inf 1001001001
#define infll 1001001001001001001LL
#define FOR0(i,n) for(int (i)=0;(i)<(n);++(i))
#define FOR1(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mp make_pair
#define pii pair<int,int>
#define ll long long
#define ld double
#define vi vector<int>
#define SZ(x) ((int)((x).size()))
#define fi first
#define se second
#define RI(n) int (n); scanf("%d",&(n));
#define RI2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
#define RI3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR0(i,sz(t))s<<t[i]<<" ";return s; }
#define dbg(vari) cerr<<#vari<<" = "<<(vari)<<endl
#define all(t) t.begin(),t.end()
#define FEACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define TESTS RI(testow)while(testow--)
#define FORZ(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define FORD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
#define gmax(a,b) (a)=max((a),(b))
#define gmin(a,b) (a)=min((a),(b))
#define ios0 ios_base::sync_with_stdio(0)
#define Ri register int
#define gc getchar()
#define il inline
il int read(){bool f=true;Ri x=0;char ch;while(!isdigit(ch=gc))if(ch=='-')f=false;while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=gc;}return f?x:-x;
}
#define gi read()
#define FO(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
#define childs(x,i) for(int i=last[x]; i; i=e[i].next)
const int N=100005,mod=1000000007;
int last[N],cnt,n,l,f[N][3],r[N],st[N];
ll d[N][3],suml,sumr[N];
struct edge{int to,next;
}e[230000];
ll mul(ll a,ll b){return ((a%mod)*(b%mod))%mod;
}
ll Plus(ll a,ll b){return (a%mod+b%mod)%mod;
}
void insert(int u, int v) {e[++cnt].next=last[u];last[u]=cnt;e[cnt].to=v;e[++cnt].next=last[v];last[v]=cnt;e[cnt].to=u;
}void dfs(int x,int fa) {int t1=1,t2=0,s1=1,s2=1,ch;childs(x,i) if((ch=e[i].to)!=fa) {ll T=0;dfs(ch,x);int mn=min(min(f[ch][0],f[ch][1]),f[ch][2]);FOR0(j,3)if(f[ch][j]==mn) T+=d[ch][j];s1=mul(s1,T);T=0;s2=mul(s2,d[ch][0]);t1+=mn;t2+=f[ch][0];}f[x][1]=t1;f[x][2]=t2;d[x][1]=s1;d[x][2]=s2;int sz=0;childs(x,i) if(e[i].to!=fa) st[++sz]=e[i].to;r[sz+1]=0; sumr[sz+1]=1;suml=1;l=0;FORD(i,sz,1) {ch=st[i];ll T=0;int mn=min(f[ch][0],f[ch][1]); FOR0(j,2)if(f[ch][j]==mn) T+=d[ch][j];r[i]=r[i+1]+mn;sumr[i]=mul(sumr[i+1],T);}f[x][0]=N;FOR1(i,sz){int fyb=l+f[st[i]][1]+r[i+1];if(fyb<f[x][0])    f[x][0]=fyb,d[x][0]=mul(d[st[i]][1],mul(suml,sumr[i+1]));else if(fyb==f[x][0])     d[x][0]=Plus(d[x][0],mul(d[st[i]][1],mul(suml,sumr[i+1])));if(f[st[i]][0]==N) break;l+=f[st[i]][0];suml=mul(suml,d[st[i]][0]);}
}
int main() {RI(n);FOR1(i,n-1)insert(gi,gi);int root=1;dfs(root,-1);int ans1=min(f[root][1],f[root][0]),ans2=0;    if(ans1==f[root][0]) ans2=Plus(ans2,d[root][0]);if(ans1==f[root][1]) ans2=Plus(ans2,d[root][1]);printf("%d\n%d\n",ans1,ans2);return 0;
}

转载于:https://www.cnblogs.com/chouti/p/5804044.html

[vijos 1770]大内密探相关推荐

  1. 【vijos】1770 大内密探(树形dp+计数)

    https://vijos.org/p/1770 不重不漏地设计状态才能正确的计数QAQ 虽然可能最优化是正确的,但是不能保证状态不相交就是作死.... 之前设的状态错了... 应该设 f[i][0] ...

  2. vijos 1006 晴天小猪历险记之Hill——数字三角形的终极变化

    题目链接:https://vijos.org/p/1006 数字三角形原题看这里:http://www.cnblogs.com/huashanqingzhu/p/7326837.html 背景 在很久 ...

  3. vijos 1476 旅游规划题解

    题目链接:https://vijos.org/p/1476 解:因为这一定是一棵树,所以我们多画几次图,就会发现所有的最长路径中心点都一样,且中心点把这条最长路径分成两段等长的路. 那么做法就很简单啦 ...

  4. Vijos P1848 记数问题【进制】

    描述 试计算在区间 1 到 n 的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1 到 11 中,即在 1.2.3.4.5.6.7.8.9.10.11 中,数字 1 出现了 4 ...

  5. Vijos P1131 最小公倍数和最大公约数问题【暴力】

    最小公倍数和最大公约数问题 描述 输入二个正整数x0,y0(2≤x0≤100000,2≤y0≤1000000),求出满足下列条件的P.Q的个数. 条件:1.P.Q是正整数 2.要求P.Q以xO为最大公 ...

  6. Vijos P1103 校门外的树【线段树,模拟】

    校门外的树 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置:数轴上的每个整数点,即0,1,2,--, ...

  7. Vijos p1165 火烧赤壁 离散化+单调栈

    题目链接:https://vijos.org/p/1165 题意:输入n(n <= 20,000)段线段的端点,问所有线段的长度总和为多少? input: 3 -1 1 5 11 2 9 out ...

  8. |Vijos|树状数组|P1512 SuperBrother打鼹鼠

    https://vijos.org/p/1512 一个二维树状数组,注意树状数组不能出现0,把所有坐标+1即可,求子矩阵和为 sub(x2,y2) - sub(x1-1,y2) - sub(x2, y ...

  9. Vijos P1756 数字反转【进制】

    背景 noip2011 NO.1 描述 给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2). ...

最新文章

  1. 公众号怎么设置滑动文字_上善.小知——(1)公众号白名单怎么设置?
  2. android java 回调方法接口
  3. java jks 转pfx_JKS和PFX文件相互转换方法
  4. 调试器工作原理--CPU软件断点/硬件断点/单步执行标识
  5. dell服务器系统备份到另一台,已解决: Re: Networker 备份服务器 备份软件配置文件备份? - Dell Community...
  6. Ubuntu把家目录文件夹名称改为英文
  7. 使用cordova,使html5也能像IOS,Android那样可以 调取手机的相机拍照功能
  8. 分水岭算法java,OpenCV 学习笔记 04 深度估计与分割——GrabCut算法与分水岭算法...
  9. java 数据结构和算法 排序
  10. 如何避免拼多多售后?拼多多售后有哪些规则?
  11. 5G业务测试方法与验证
  12. 如何成为一名合格的运筹优化算法工程师?
  13. Bean对象的拷贝方法BeanCopier和BeanUtils
  14. 美团后台开发秋招面经汇总(更新至2021-08-13)
  15. Flowable入门系列文章194 - JMX的基本介绍和属性说明
  16. vue组件强制刷新的方案
  17. iOS开发-AppDelegate
  18. Win10系统Chrome浏览器启用独立显卡提升3D程序渲染性能
  19. 【PCB开源分享】STC8A8K64D4开发板
  20. ip地址转换数字函数 iton_3. IP地址转换函数

热门文章

  1. java开发微信公众号(SpringMVC)2-消息管理功能
  2. 定制传承银鲨耀世,iGame Z390旗舰电竞主板品鉴
  3. 朗道十卷《力学》笔记(更新中)
  4. lidar_align 标定lidar和imu 在“Performing Global Optimization”步骤终止的问题
  5. 知识表示学习研究进展
  6. 从.weights中提取权重数据
  7. 【ISP】浅析Lens Shading
  8. 虚幻引擎之自定义着色模型(ShadingModel)
  9. STM32之DAC音频播放
  10. C语言:习题11-1 输出月份英文名.2021-07-25