• hdu 5739 割点


    Fantasia

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1654    Accepted Submission(s): 429


    Problem Description
    Professor Zhang has an undirected graph G with n vertices and m edges. Each vertex is attached with a weight wi. Let Gi be the graph after deleting the i-th vertex from graph G. Professor Zhang wants to find the weight of G1,G2,...,Gn.

    The weight of a graph G is defined as follows:

    1. If G is connected, then the weight of G is the product of the weight of each vertex in G.
    2. Otherwise, the weight of G is the sum of the weight of all the connected components of G.

    A connected component of an undirected graph G is a subgraph in which any two vertices are connected to each other by paths, and which is connected to no additional vertices in G.
     
    Input
    There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

    The first line contains two integers n and m (2n105,1m2×105) -- the number of vertices and the number of edges.

    The second line contains n integers w1,w2,...,wn (1wi109), denoting the weight of each vertex.

    In the next m lines, each contains two integers xi and yi (1xi,yin,xiyi), denoting an undirected edge.

    There are at most 1000 test cases and n,m1.5×106.
     
    Output
    For each test case, output an integer S=(i=1nizi) mod (109+7), where zi is the weight of Gi.
     
    Sample Input
    1 3 2 1 2 3 1 2 2 3
     
    Sample Output
    20
     
    /*
    hdu 5739 割点
    
    problem:
    给你一个无向图,G[i]为删除i点时,无向图的价值.  求 sum(i*G[i])%mod
    如果当前是连通的,那么连通分量的价值为所有点权值的积(任意两个节点连通)
    否则为拆分后的各个连通分量的价值的和
    
    solve:
    所以需要判断当前点是否是割点.
    如果不是割点,只需要减去这个点的权值即可. 如果是割点,要减去这个连通分量的价值再加上拆散后的各个连通分量的值
    
    最开始题意理解错了- -,而且模板有点问题,一直wa.
    
    hhh-2016-08-27 19:47:17
    */
    #pragma comment(linker,"/STACK:124000000,124000000")
    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <math.h>
    #include <queue>
    #include <map>
    #define lson  i<<1
    #define rson  i<<1|1
    #define ll long long
    #define clr(a,b) memset(a,b,sizeof(a))
    #define scanfi(a) scanf("%d",&a)
    #define scanfl(a) scanf("%I64d",&a)
    #define key_val ch[ch[root][1]][0]
    #define inf 1e9
    using namespace std;
    const ll mod = 1e9+7;
    const int maxn = 100005;
    
    struct Edge
    {
        bool cut ;
        int v,next,w;
    } edge[maxn*5];
    
    int head[maxn],tot;
    int low[maxn],dfn[maxn],Stack[maxn],index,top;
    bool Instack[maxn],cut[maxn];
    int bridge;
    ll val[maxn],mul[maxn],ans[maxn],fans[maxn],tval[maxn];
    void add_edge(int u,int v)
    {
        edge[tot].v = v,edge[tot].next = head[u],head[u] = tot++;
    }
    
    ll tans  =1 ;
    
    ll pow_mod(ll a,ll n)
    {
        ll cnt =1 ;
        while(n)
        {
            if(n & 1) cnt = cnt*a%mod;
            a = a*a%mod;
            n >>= 1;
        }
        return cnt ;
    }
    int now;
    vector<int> vec[maxn];
    int from[maxn];
    void Tarjan(int u,int ance,int pre)
    {
        int v;
        vec[now].push_back(u);
        from[u] = now;
        low[u] = dfn[u] = ++index;
        Stack[top++] = u;
        Instack[u] = true;
        tans = tans*val[u] % mod;
        int son = 0;
        for(int i= head[u]; i!= -1; i = edge[i].next)
        {
            v = edge[i].v;
            if(v == pre){
                continue;
            }
            if(!dfn[v])
            {
                son ++ ;
                ll tp = tans;
                Tarjan(v,ance,u);
                low[u] = min(low[u],low[v]);
    
                if(u != pre && low[v] >= dfn[u])
                {
                    cut[u] = true;
                    ll ta = tans * pow_mod(tp,mod-2)%mod;
    //                cout <<"node:" << u <<" ta:" <<ta <<endl;
                    ans[u] = (ans[u] + ta)%mod;
                    fans[u] = (fans[u] * ta) % mod;
                }
            }
            else if(low[u] > dfn[v])
                low[u] = dfn[v];
        }
        if(u == ance && son > 1)
            cut[u] = true;
        Instack[u] = false;
        top --;
    }
    
    void init(int n)
    {
        for(int i = 0; i <= n+1; i++)
        {
            head[i] = -1;
            ans[i] = 0;
            fans[i] = 1;
            Instack[i]=cut[i]= 0;
            dfn[i] = 0;
            vec[i].clear();
        }
        tot=top=index=0;
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        int T,n,m,u,v;
    
        scanfi(T);
        while(T--)
        {
    
            scanfi(n),scanfi(m);
            init(n);
            for(int i =1; i <= n; i++)
            {
                scanfl(val[i]);
                fans[i] = 1;
            }
            for(int i = 0; i < m; i++)
            {
                scanfi(u),scanfi(v);
                add_edge(u,v);
                add_edge(v,u);
            }
            now = 1;
            ll ob = 0;
            for(int i = 1; i <= n; i++)
            {
                if(!dfn[i])
                {
                    tans= 1;
                    Tarjan(i,i,-1);
                    tval[now] = tans;
                    ll amul = tans;
                    ob = (ob+tans) %mod;
    //                cout << "all:" <<tans<<endl;
                    for(int j = 0 ; j < vec[now].size(); j ++)
                    {
                        int to = vec[now][j];
    
    //                    cout << to <<" " << fans[to] << endl;
                        if(to == i) continue;
                        ans[to] = (ans[to] + amul*pow_mod(fans[to]*val[to]%mod,mod-2)%mod);
                        if(ans[to] > mod) ans[to] -= mod;
                    }
                    now ++;
                }
            }
            ll out = 0;
            ll tm;
            for(int i = 1; i <= n; i++)
            {
    //            cout << fans[i] <<" " << ans[i] <<" "  <<cut[i] << endl;
                int tf = from[i];
                if(cut[i])
                {
                    tm = (ob - tval[tf] + ans[i] + mod)%mod;
                }
                else
                {
                    if(vec[from[i]].size() > 1)
                        tm = (ob - tval[tf] + tval[tf]*pow_mod(val[i],mod-2)%mod + mod) % mod;
                    else
                        tm = (ob - tval[tf] + mod) % mod;
                }
                out = (out + i * tm % mod) % mod;
            }
            printf("%I64d
    ",out);
        }
        return 0;
    }
    
    
    /*
    3
    4 3
    1 2 3 4
    1 2
    2 3
    1 3
    
    4 2
    100000000 131231232 312354435 432134234
    1 2
    3 4
    
    66
    315142079
    
    */
    

      

  • 相关阅读:
    python读取xml文件报错ValueError: multi-byte encodings are not supported
    使用命令创建jenkins的job,解决jenkinsapi.custom_exceptions.JenkinsAPIException错误
    使用Python命令创建jenkins的job
    使用selenium grid分布式执行之一
    使用python 操作liunx的svn,方案二
    使用python 操作liunx的svn,方案一
    使用shell脚本实现在liunx上进行svn的上传下载更新功能
    java连接ssh执行shell脚本
    perl学习(二)正则表达式
    googletest进行单元测试(使用cmake编译)
  • 原文地址:https://www.cnblogs.com/Przz/p/5813676.html
Copyright © 2020-2023  润新知