除转载的四道例题外,还有
hdu 4670
******************************************************分割线,接下来是代码**************************************************
//BZOJ 2599
//点按[1,n]存,0有特殊用
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
#define N 200005
#define C 1000005
struct edge{
int to,next,w;
}e[N<<1];
int n,m;
int root,size,ans,o;
int s[N],f[N],d[N],ee[N],head[N],c[C],v[C];
vector<int> dep;
bool done[N];
void add(int x,int y,int z)
{
e[o].to=y;
e[o].w=z;
e[o].next=head[x];
head[x]=o++;
}
void getroot(int now, int fa) {
int u;
s[now] = 1; f[now] = 0;
for (int i=head[now]; ~i; i=e[i].next)
if ((u =e[i].to)!= fa)
{ if (done[u]) continue;
getroot(u, now);
s[now] += s[u];
f[now] = max(f[now], s[u]);
}
f[now] = max(f[now], size-s[now]);
if (f[now] < f[root]) root = now;
}
void dfs1(int now, int fa) {
int u;
if (d[now] > m) return;
if (v[m-d[now]] == root)
ans=min(ans,c[m-d[now]] + ee[now]);
for (int i = head[now]; ~i; i = e[i].next)
if ((u =e[i].to)!= fa)
{ if (done[u]) continue;
d[u] = d[now] + e[i].w;
ee[u] = ee[now] + 1;
dfs1(u, now);
}
}
void dfs2(int now, int fa) {
int u;
if (d[now] > m) return;
if (v[d[now]] != root) {
c[d[now]] = ee[now];
v[d[now]] = root;
}
else
c[d[now]]=min(c[d[now]],ee[now]);
for (int i = head[now]; ~i; i = e[i].next)
if ((u =e[i].to)!= fa)
{ if (done[u]) continue;
dfs2(u, now);
}
}
void work(int now) {
int u;
v[0]=root;
done[now] = true;
for (int i=head[now]; ~i; i=e[i].next)
if (!done[u =e[i].to])
{ d[u] = e[i].w;
ee[u] = 1;
dfs1(u, now);
dfs2(u, now);
}
for (int i=head[now]; ~i; i=e[i].next)
if (!done[u =e[i].to])
{
f[0] = size = s[u]; getroot(u, root=0); work(root);
}
}
void doit()
{
ans = n; memset(done, 0, sizeof(done));
memset(head,255,sizeof(head)); o=0;
for (int i=1,x,y,w; i<n; i++)
{
scanf("%d%d%d", &x, &y, &w);x++; y++;
add(x,y,w);
add(y,x,w);
}
f[0] = size = n; getroot(1, root=0); work(root);
printf("%d\n", ans < n ? ans : -1);
}
int main()
{ while (scanf("%d%d",&n,&m)!=EOF) doit();
return 0;
}
/*
4 3
0 1 1
1 2 2
1 3 4
*/
//Hdu 4670
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <map>
using namespace std;
#define N 50005
#define C 100005
#define T 32
typedef long long LL;
struct edge{
int to,next;
}e[N<<1];
int n,root,size,o,pr,equ,oo;
LL ans,total[T];
map<LL,int> mm;
int s[N],f[N],d[N][T],head[N],c[C];
LL res[C];
LL pri[T];
vector<int> dep;
bool done[N];
int num[N][T];
void add(int x,int y)
{
e[o].to=y;
e[o].next=head[x];
head[x]=o++;
}
void getroot(int now, int fa) {
int u;
s[now] = 1; f[now] = 0;
for (int i=head[now]; ~i; i=e[i].next)
if ((u =e[i].to)!= fa)
{ if (done[u]) continue;
getroot(u, now);
s[now] += s[u];
f[now] = max(f[now], s[u]);
}
f[now] = max(f[now], size-s[now]);
if (f[now] < f[root]) root = now;
}
void dfs(int now,int fa)
{ int tmp,u;
LL s1=0,s2=0;
for (int i=0;i<pr;i++)
{
d[now][i]=d[fa][i]+num[now][i];
if (d[now][i]>2) d[now][i]-=3;
tmp=(total[i]+3-d[now][i])%3;
s1=s1*3+d[now][i];
s2=s2*3+tmp;
}
if (s1==s2) equ++;
if (mm.find(s1)==mm.end()) {mm[s1]=oo;res[oo]=s2;c[oo++]=1;}else {c[mm[s1]]++;}
for (int i=head[now];~i;i=e[i].next)
if ((u=e[i].to)!=fa)
{ if (done[u]) continue;
dfs(u, now);
}
}
LL calc(int now,int fa)
{
mm.clear();//memset(c,0,sizeof(c)); 加上这句会T
equ=0; oo=0;
if (fa)
for (int i=0;i<pr;i++) total[i]=num[fa][i];
else for (int i=0;i<pr;i++) total[i]=num[now][i];
dfs(now,fa);
LL re=0;
for (int i=0;i<oo;i++)
{ if (mm.find(res[i])!=mm.end())
re+=c[i]*c[mm[res[i]]];
}
return (re-equ)/2+equ;
}
void work(int now) {
int u;
done[now] = true;
ans+=calc(root,0);
for (int i=head[now]; ~i; i=e[i].next)
if (!done[u =e[i].to])
{ ans-=calc(u,now);
f[0] = size = s[u]; getroot(u, root=0); work(root);
}
}
void doit()
{ ans = 0; memset(done, 0, sizeof(done));
scanf("%d",&pr);
for (int i=0;i<pr;i++)
scanf("%I64d",&pri[i]);
memset(num,0,sizeof(num));
for (int i=1;i<=n;i++)
{ LL x;
scanf("%I64d",&x);
for (int j=0;j<pr;j++)
{ while (x%pri[j]==0)
{
x/=pri[j];
num[i][j]++;
}
num[i][j]%=3;
}
}
memset(head,255,sizeof(head)); o=0;
for (int i=1,x,y; i<n; i++)
{
scanf("%d%d", &x, &y);
add(x,y);
add(y,x);
}
f[0] = size = n; getroot(1, root=0); work(root);
printf("%I64d\n",ans);
}
int main()
{ while (scanf("%d",&n)!=EOF) doit();
return 0;
}
/*
4
2 2 5
100 10 100 10
1 2
2 3
3 4
7
1 2
2 2 2 2 2 2 2
1 2
1 3
2 4
2 5
3 6
3 7
5
3 2 3 5
2500 200 9 270000 27
4 2
3 5
2 5
4 1
6
3 2 3 5
6 1 30 150 150 12
1 2
2 4
1 3
3 5
3 6
ans:
4
7
1
4
*/