2020 cattle off winter training camp 1 maki basic algorithm and tree

topic

   One day, maki got the tree. The so-called tree, i.e. no loopback, multiple edges and undirected circuit of FIG.
  The tree has vertices, edges. Each vertex is dyed white or black.
  maki want to know, take two different points, there is a simple path on their one and only one point of emulated black How many?
  Note:
      ① means a simple path tree connecting two points of the shortest.
      ② and emulated treated as the same.

  Enter a description:

      The first line a positive integer . It represents the number of vertices.

      The second line is the only one character string 'B' and 'W' thereof. The i- th character is the B represents the points are black, W represents the point are white.

      The next lines of two positive integers , the representative points and the points are connected with a one side

  Output Description:

      A positive integer representing the number of paths after only a black point.

answer

  + Disjoint-set count.

  After only a black point of no more than two paths, white point ① ends, the middle of a black dot; ② either end of the black spot.

  Pretreatment, the maximum communication processing of each block of the white point out, the recording size.

  If a black dot is connected to the white point of k, so that f (i) is the i th white point communication block size ( ).

  The number of cases of ① is satisfied:

  ② meet the number of cases is as follows:

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int N,f[maxn],link[maxn];
string is_wb;
vector<int> edge[maxn];
int find(int p);
void merge(int u,int v);
long long cal();
int main()
{
   {
      fill(f,f+maxn,-1);
   }
   int i,u,v;
   scanf("%d",&N);
   cin>>is_wb;
   for(i=1;i<N;i++)
   {
      scanf("%d%d",&u,&v);
      edge[u].push_back(v);
      edge[v].push_back(u);
      if(is_wb[u-1]=='W' && is_wb[v-1]=='W')
         merge(u,v);
   }
   printf("%lld",cal());
   system("pause");
   return 0;
}
int find(int p)
{
   return f[p]==-1?p:f[p]=find(f[p]);
}
void merge(int u,int v)
{
   int x,y;
   x=find(u);
   y=find(v);
   if(x!=y)
   {
      f[x]=y;
      link[y]+=link[x]+1;
   }
}
long long cal()
{
   int i,j;
   long long ans=0;
   for(i=1;i<=N;i++)
   {
      vector<int> v;
      vector<int> pre_v;
      v.push_back(0);
      pre_v.push_back(0);
      if(is_wb[i-1]=='W') continue;
      for(j=0;j<edge[i].size();j++)
      {
         if(is_wb[edge[i][j]-1]=='B') continue;
         v.push_back(link[find(edge[i][j])]+1);
         pre_v.push_back(link[find(edge[i][j])]+1+pre_v.back());
      }
      for(j=1;j<v.size();j++)
         ans+=v[j]*(pre_v.back()-pre_v[j]);
      ans+=pre_v.back();
   }
   return ans;
}

Guess you like

Origin www.cnblogs.com/VividBinGo/p/12290669.html