bzoj3573[Hnoi2014]米特运输

http://www.lydsy.com/JudgeOnline/problem.php?id=3573

好吧,虽然这是day1最后一题,但却是最水的一题。。。。(前提:看懂题目)

仔细看题!

仔细看题!

仔细看题!

看懂题后就知道设第$i$个点的儿子节点的个数为$degree[i]$,容量为$A[i]$,我们要修改最少的点的容量,使得每个点$i$的儿子的容量均为$\frac{A[i]}{degree[i]}$

我们发现如果一个点的容量是确定的,那么整个树的容量都是确定的

我们记第$i$个点的所有祖先的$degree$的乘积为$P[i]$,如果第$i$个点无需修改,那么根结点的容量应该为$P[i]*A[i]$

我们要找到最多的点使得$P[i]*A[i]$相同即可

用一个map维护即可

但是$P[i]$有可能非常大,我们哈希一下即可

。。。。。。。。。。。。。。。

。。。。。。。。。。。。。。。

。。。。。。。。。。。。。。。

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<utility>
#include<set>
#include<bitset>
#include<vector>
#include<functional>
#include<deque>
#include<cctype>
#include<climits>
#include<complex>
#include<cassert> 
//#include<bits/stdc++.h>适用于CF,UOJ,但不适用于poj
 
using namespace std;

typedef long long LL;
typedef double DB;
typedef pair<int,int> PII;
typedef pair<DB,DB> PDD;
typedef complex<DB> CP;
typedef vector<int> VI;

#define mmst(a,v) memset(a,v,sizeof(a))
#define mmcy(a,b) memcpy(a,b,sizeof(a))
#define fill(a,l,r,v) fill(a+l,a+r+1,v)
#define re(i,a,b)  for(i=(a);i<=(b);i++)
#define red(i,a,b) for(i=(a);i>=(b);i--)
#define fi first
#define se second
#define mp(a,b) make_pair(a,b)
#define pb(a) push_back(a)
#define SF scanf
#define PF printf
#define two(k) (1<<(k))
#define SZ(x) (int(x.size()))
#define all(x) (x).begin(),(x).end()
#define ire(i,v,x) for(i=0,v=i<SZ(x)?x[i]:0;i<SZ(x);v=x[++i])


template<class T>inline T sqr(T x){return x*x;}
template<class T>inline void upmin(T &t,T tmp){if(t>tmp)t=tmp;}
template<class T>inline void upmax(T &t,T tmp){if(t<tmp)t=tmp;}

inline int sgn(DB x){if(abs(x)<1e-9)return 0;return(x>0)?1:-1;}
const DB Pi=acos(-1.0);

int gint()
  {
        int res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }
LL gll()
  {
      LL res=0;bool neg=0;char z;
        for(z=getchar();z!=EOF && z!='-' && !isdigit(z);z=getchar());
        if(z==EOF)return 0;
        if(z=='-'){neg=1;z=getchar();}
        for(;z!=EOF && isdigit(z);res=res*10+z-'0',z=getchar());
        return (neg)?-res:res; 
    }

const int maxn=501000;
const LL MOD[]={1000000007LL,813413241LL,2421544587LL};

typedef map<pair<pair<LL,LL>,LL>,int> MLLL;

int n;
int A[maxn];
LL P[maxn][3];

MLLL S;
int now,info[maxn];
struct Tedge{int v,next;}edge[2*maxn];
int degree[maxn];
int fa[maxn],head,tail,que[maxn];

void addedge(int u,int v){edge[++now]=(Tedge){v,info[u]};info[u]=now;}

int main()
  {
      freopen("meat.in","r",stdin);
      freopen("meat.out","w",stdout);
      int i,j;
      n=gint();
      re(i,1,n)A[i]=gint();
      mmst(info,-1);now=-1;
      re(i,1,n-1){int u=gint(),v=gint();addedge(u,v);degree[u]++;degree[v]++;}
      re(i,2,n)degree[i]--;
      que[head=tail=1]=1;
      re(j,0,2)P[1][j]=1;
      while(head<=tail)
        {
            int u=que[head++],v;
            for(i=info[u],v=edge[i].v;i!=-1;i=edge[i].next,v=edge[i].v)if(v!=fa[u])
              {
                  fa[que[++tail]=v]=u;
                  re(j,0,2)P[v][j]=P[u][j]*LL(degree[u])%MOD[j];
              }
        }
      re(i,1,n)re(j,0,2)P[i][j]=P[i][j]*LL(A[i])%MOD[j];
      re(i,1,n)S[mp(mp(P[i][0],P[i][1]),P[i][2])]++;
      int ans=0;
      for(MLLL::iterator it=S.begin();it!=S.end();it++)upmax(ans,it->se);
      ans=n-ans;
      cout<<ans<<endl;
      return 0;
  }
View Code

 

posted @ 2016-02-25 22:09  maijing  阅读(352)  评论(0编辑  收藏  举报