zoukankan      html  css  js  c++  java
  • 解题:APIO 2018 铁人两项

    题面

    建立圆方树,考虑所有路径,发现路径上原来的点双(现在的方点)里的点都可以做中间点。但是路径上被方点夹着的圆点被计重了,要扣掉;枚举的两个端点也被算进去了,要扣掉。所以直接将方点权值设为点双大小,圆点权值设为-1,所有圆点间路径权值和的和即为答案

    注意图可能不连通,草(汉语)

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 const int N=200005,M=400005;
     7 int n,m,r,c,t1,t2,cnt,Cnt,tot,top; long long sum,ans;
     8 int dfn[N],low[N],col[N],isc[N],stk[N],siz[N],dis[N];
     9 int p[N],noww[M],goal[M],P[N],Noww[M],Goal[M],val[N];
    10 vector<int> ve[N]; 
    11 void Link(int f,int t)
    12 {
    13     noww[++cnt]=p[f];
    14     goal[cnt]=t,p[f]=cnt;
    15     noww[++cnt]=p[t];
    16     goal[cnt]=f,p[t]=cnt;
    17 }
    18 void Linka(int f,int t)
    19 { 
    20     Noww[++Cnt]=P[f];
    21     Goal[Cnt]=t,P[f]=Cnt;
    22     Noww[++Cnt]=P[t];
    23     Goal[Cnt]=f,P[t]=Cnt;
    24 }
    25 void Tarjan_PBC(int nde)
    26 { 
    27     int tep=0; stk[++top]=nde;
    28     dfn[nde]=low[nde]=++tot;
    29     for(int i=p[nde];i;i=noww[i])
    30         if(!dfn[goal[i]])
    31         {
    32             Tarjan_PBC(goal[i]);
    33             low[nde]=min(low[nde],low[goal[i]]);
    34             if(dfn[nde]<=low[goal[i]])
    35             {
    36                 if(nde!=r||++tep>1) isc[nde]=true;
    37                 int tmp; c++;
    38                 do
    39                 {
    40                     tmp=stk[top--],col[tmp]=c;
    41                     ve[c].push_back(tmp);
    42                 }while(tmp!=goal[i]);
    43                 ve[c].push_back(nde);
    44             }
    45         }
    46         else low[nde]=min(low[nde],dfn[goal[i]]);
    47 }
    48 void DFS(int nde,int fth)
    49 {
    50     if(nde<=n) siz[nde]=1;
    51     for(int i=P[nde];i;i=Noww[i])
    52         if(Goal[i]!=fth) DFS(Goal[i],nde),siz[nde]+=siz[Goal[i]];
    53 }
    54 void Getans(int nde,int fth)
    55 {
    56     long long tmp=0;
    57     int sizz=tot-siz[nde];
    58     for(int i=P[nde];i;i=Noww[i])
    59         if(Goal[i]!=fth) 
    60         {
    61             int G=Goal[i],S=siz[G];
    62             tmp+=1ll*sizz*S,sizz+=S;
    63             Getans(Goal[i],nde);
    64         }
    65     if(nde<=n) ans-=(tmp+tot-1)*2;
    66     else ans+=2*tmp*val[nde];
    67 }
    68 int main()
    69 {
    70     scanf("%d%d",&n,&m);
    71     for(int i=1;i<=m;i++)
    72         scanf("%d%d",&t1,&t2),Link(t1,t2);
    73     for(int i=1;i<=n;val[i]=-1,i++)
    74         if(!dfn[i]) r=i,Tarjan_PBC(i);
    75     for(int i=1;i<=c;i++)
    76     {
    77         val[n+i]=ve[i].size();
    78         for(int j=0;j<val[n+i];j++) 
    79             Linka(n+i,ve[i][j]);
    80     }
    81     for(int i=1;i<=n;i++)
    82         if(!siz[i]) DFS(i,0),tot=siz[i],Getans(i,0);
    83     printf("%lld",ans);
    84     return 0;
    85 }
    View Code
  • 相关阅读:
    学生党 应该去 研究研究 Socket(套接字) 实现原理
    收录一些 硬件 相关的 文章
    谈谈 软件 开源项目
    我决定 开启 一个 人工智能 机器学习 技术 的 普及项目 Let it Learn
    我邀请 民科吧 网友 和 三江老师 来 反相吧 辩论 调和级数
    共量子论 丢番图方程组 数值求解 最小分子解
    刚 看了一下 一元三次方程 的 解法
    研究发展 C 语言
    对 量子病态定理 提出的 代数方程 不成立 的 证明
    数学 改革
  • 原文地址:https://www.cnblogs.com/ydnhaha/p/10392496.html
Copyright © 2011-2022 走看看