zoukankan      html  css  js  c++  java
  • luogu 4630 [APIO2018] Duathlon 铁人两项

    题目大意:

    无向图上找三个点 a b c使存在一条从a到b经过c的路径

    求取这三个点的方案数

    思路:

    建立圆方树

    这个圆方树保证没有两个圆点相连或两个方点相连

    对于每个节点x 设该节点为路径的中间节点

    则a c要么同在一个子树内 要么一个在子树内另一个在子树外 最后对答案<<1

    对于每个方点设val[x] 为该点所连圆点的个数

    每个方点按照两种情况算出答案之后

    用圆点减去算重的部分

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<vector>
     9 #define ll long long
    10 #define inf 2139062143
    11 #define MAXN 100100
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 int n,m,fst[MAXN],cnt,nxt[MAXN<<2],to[MAXN<<2];
    21 int st[MAXN],top,dfn[MAXN],low[MAXN],stp,sz[MAXN<<1],val[MAXN<<1],sumsz;
    22 ll ans=0;
    23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;}
    24 vector<int>son[MAXN<<1];
    25 inline void tarjan(int x,int fa)
    26 {
    27     dfn[x]=low[x]=++stp,st[++top]=x;
    28     sz[x]=1,val[x]=-1;int now=0;
    29     for(int i=fst[x];i;i=nxt[i])
    30         if(!dfn[to[i]])
    31         {
    32             tarjan(to[i],x);low[x]=min(low[x],low[to[i]]);
    33             if(low[to[i]]<dfn[x]) continue;val[++m]=1;
    34             do{now=st[top--],son[m].push_back(now),sz[m]+=sz[now],val[m]++;}
    35             while(now!=to[i]);
    36             son[x].push_back(m);sz[x]+=sz[m];
    37         }
    38         else low[x]=min(low[x],dfn[to[i]]);
    39 }
    40 void dfs(int x,int tot)
    41 {
    42     int tmp= x<=n;
    43     for(int i=0;i<son[x].size();i++)
    44     {
    45         dfs(son[x][i],tot);ans+=(ll)tmp*sz[son[x][i]]*val[x];tmp+=sz[son[x][i]];
    46     }
    47     ans+=(ll)sz[x]*(tot-sz[x])*val[x];
    48 }
    49 int main()
    50 {
    51     n=read(),m=read();int a,b;
    52     while(m--){a=read(),b=read();add(a,b);add(b,a);}
    53     m=n;
    54     for(int i=1;i<=n;i++)
    55         if(!dfn[i]){tarjan(i,0);dfs(i,sz[i]);}
    56     printf("%lld
    ",ans<<1);
    57 }
    View Code
  • 相关阅读:
    HttpClient调用RestFul接口(post和get方式)
    mysql权限异常
    javascript:用法
    Java哈希值HashCode理解
    Java的CountDownLatch和CyclicBarrier的理解和区别
    Java并发编程与技术内幕:ThreadGroup线程组应用
    面试官: 谈谈什么是守护线程以及作用 ?
    java 成员变量 静态成员变量 方法 静态方法初始化顺序
    【java并发核心一】Semaphore 的使用思路
    threadlocal原理及常用应用场景
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9349717.html
Copyright © 2011-2022 走看看