zoukankan      html  css  js  c++  java
  • HDU5739:Fantasia——题解

    http://acm.hdu.edu.cn/showproblem.php?pid=5739

    定义一个连通图的权值为所有顶点点权乘积,定义一个无向图的权值为这个无向图的所有极大连通子图权值和,现给出一张有$n$个点的无向图,每个点有点权$w_i$,设删去节点i后此图权值为$z_i$,求

    圆方树处理一下可知删掉一个圆点后所形成的每个连通块里的圆点和你在原图删掉这个点后所形成的每个连通块里的点是一样的。

    于是令$w[i]$为以$i$为根的子树的每个点的$w$的乘积,当然令方点的$w$为1,那么$z[u]=sigma(w[v])+sigma(w[rt])$,其中$v$是以$u$为根的树$u$的儿子,$rt$为其他的树的树根。

    枚举每个圆点求解即可。

    #include<cmath>
    #include<queue>
    #include<stack>
    #include<cstdio>
    #include<cctype>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int p=1e9+7;
    const int N=2e5+5;
    const int M=4e5+5;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    inline ll qpow(ll k,int n){
        ll res=1;
        while(n){
            if(n&1)res=res*k%p;
            k=k*k%p;n>>=1;
        }
        return res;
    }
    struct node{
        int u[M],v[M],nxt[M];
        int cnt,head[N];
        void init(){
            cnt=0;
               memset(head,0,sizeof(head));
        }
        void add(int U,int V){
            u[++cnt]=U;v[cnt]=V;nxt[cnt]=head[U];head[U]=cnt;
        }
    }e,g;
    int n,m;
    int dfn[N],low[N],to[N],t,l;
    ll w[N];
    stack<int>q;
    void tarjan(int u,int f){
        dfn[u]=low[u]=++t;
        for(int i=g.head[u];i;i=g.nxt[i]){
            int v=g.v[i];
            if(!dfn[v]){
                q.push(i);
                tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]){
                    int num;l++;
                    do{
                        num=q.top();q.pop();
                        int uu=g.u[num],vv=g.v[num];
                        if(to[uu]!=l){
                            to[uu]=l;
                            e.add(uu,l+n);e.add(l+n,uu);
                            w[l+n]=1;
                        }
                        if(to[vv]!=l){
                            to[vv]=l;
                            e.add(vv,l+n);e.add(l+n,vv);
                            w[l+n]=1;
                        }
                    }while(num!=i);
                }
            }else if(low[u]>dfn[v]&&f!=v){
                q.push(i);
                low[u]=dfn[v];
            }
        }
    }
    ll ans,sum;
    vector<int>root;
    void dfs1(int u,int f){
        for(int i=e.head[u];i;i=e.nxt[i]){
            int v=e.v[i];
            if(f==v)continue;
            dfs1(v,u);w[u]=w[u]*w[v]%p;
        }
    }
    void dfs2(int u,int f,int rt){
        for(int i=e.head[u];i;i=e.nxt[i]){
            int v=e.v[i];
            if(f==v)continue;
            dfs2(v,u,rt);
            if(u<=n)ans=(ans+w[v]*u%p)%p;
        }
        if(u<=n){
            if(u!=rt)ans=(ans+w[rt]*qpow(w[u],p-2)%p*u%p)%p;
            ans=((ans+(sum-w[rt])*u%p)%p+p)%p;
        }
    }
    void init(){
        root.clear();
        for(int i=1;i<=n*2;i++){
            e.head[i]=g.head[i]=0;
            dfn[i]=low[i]=to[i]=0;
        }
        e.cnt=g.cnt=0;
        t=l=0;ans=sum=0;
    }
    int main(){
        int T=read();
        while(T--){
            n=read(),m=read();
            for(int i=1;i<=n;i++)w[i]=read();
            for(int i=1;i<=m;i++){
                int u=read(),v=read();
                g.add(u,v);g.add(v,u);
            }
            for(int i=1;i<=n;i++){
                if(!dfn[i]){
                    tarjan(i,0);dfs1(i,0);
                    root.push_back(i);
                    sum=(sum+w[i])%p;
                }
            }
            for(int i=0;i<root.size();i++){
                dfs2(root[i],0,root[i]);
            }
            printf("%lld
    ",ans);
            init();
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    【设计模式】模板模式
    【设计模式】策略模式
    【设计模式】空对象模式
    【设计模式】状态模式
    【设计模式】观察者模式
    【设计模式】备忘录模式
    【设计模式】中介者模式
    【设计模式】迭代器模式
    【设计模式】解释器模式
    【设计模式】命令模式
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12599343.html
Copyright © 2011-2022 走看看