您的位置:首页 > 其它

省队集训 water

2015-07-11 17:02 387 查看
题目大意:有n个瓶子,都是m高,有些中间连了一些水管 (保证是一棵树),给出每个瓶子的底座高度h,以及水管,现在要在每个瓶子中灌水,然后会像连通器那样流起来,求有多少种每个瓶子水都是整数的静止方案数(带mod)  n<=1000 m<=10^6

这题比较水,但是还是没写出来

用类似点分治的思想

首先找到底座最高的那个瓶子x,如果它上面有水,那么显然所有的瓶子上都有水,且高度一样。如果它上面没有水,那么它所有的儿子的高度都不超过h[x],然后递归处理儿子就行了(初始可以看成高度不超过m)

复杂度O(n^2)

代码很好写,5min就写完了

#include<bits/stdc++.h>
using namespace std;
const int maxn=1011,mod=1000000007;
int n,m;
int tot=1,now[maxn],pre[maxn<<1],son[maxn<<1];
void add(int a,int b){
pre[++tot]=now[a]; now[a]=tot; son[tot]=b;
}
void cc(int a,int b){add(a,b); add(b,a);}
int h[maxn];
void init(){
scanf("%d%d",&n,&m);
for (int i=1,a,b;i<n;++i) scanf("%d%d",&a,&b),cc(a,b);
for (int i=1;i<=n;++i) scanf("%d",h+i);
}
int findmax(int x,int fa=0){
int res=x;
for (int p=now[x];p;p=pre[p]) if (son[p]!=fa){
int tmp=findmax(son[p],x);
if (h[tmp]>h[res]) res=tmp;
}
return res;
}
int gao(int x,int lim){
int res=1;
for (int p=now[x];p;p=pre[p]) if (son[p]){
son[p^1]=0; res=1LL*res*gao(findmax(son[p]),h[x])%mod;
}
res=(res+lim-h[x])%mod;
}
void work(){
printf("%d\n",gao(findmax(1),m));
}
int main(){
init();
work();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: