• HDU


    题意

    给你n个点m条边,并且保证整个图是仙人掌。

    仙人掌:每条边仅属于1条或者0条回路

    且无重边和自环

    让你删掉一些边使其变成一棵树(拥有点数-1条边)

    注意一个点也是森林

    图可能是不联通的

    思路

    考虑环,显然一个环可以随便去掉几条边但是至少一条(也就是说不能是(C_n^0))(2^{x})-1,然后考虑非环那么共有m-(所有环的边数),然后可以随便去除边共(2^{m-cnt})

    在找环时,求环的边数见(dfs)

    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define int long long
    const int maxn=3e5+10;
    int dep[maxn],cnt;
    vector<int>edge[maxn];
    const int mod=998244353;
    int ans;
    int qp(int a,int b) {
        int res=1;
        while(b) {
            if(b&1)res=res*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return res;
    }
    
    void dfs(int u,int fa) {
        dep[u]=dep[fa]+1;
        for(int i=0; i<edge[u].size(); ++i) {
            int v=edge[u][i];
            if(v==fa)continue;
            if(!dep[v])dfs(v,u);
            else if(dep[u]>dep[v]){
                ans=(ans%mod*(qp(2,dep[u]-dep[v]+1)-1)%mod)%mod;
                cnt+=dep[u]-dep[v]+1;
            }
        }
    }
    
    
    signed main() {
        int n,m;
        while(~scanf("%lld%lld",&n,&m)) {
            cnt=0;
            for(int i=1; i<=n; ++i)dep[i]=0,edge[i].clear();
            for(int i=1; i<=m; ++i) {
                int u,v;
                scanf("%lld%lld",&u,&v);
                edge[u].push_back(v);
                edge[v].push_back(u);
            }
            ans=1;
            for(int i=1; i<=n; ++i) {
                if(!dep[i])dfs(i,0);
            }
            ans=(ans%mod*(qp(2,m-cnt))%mod)%mod;
            printf("%lld
    ",ans);
        }
    
    }
    
  • 相关阅读:
    上海社保,统筹内不能转出的疑惑
    c# 代理IP获取通用方法
    element-ui 的el-button组件中添加自定义颜色和图标的实现方法
    前端实现打印功能
    elementUI表格合并单元格
    webpack打包图片资源找不到问题
    Webstorm/IntelliJ Idea 过期破解方法
    ES6 Promise 用法讲解
    移动端开发
    Stylus的基础用法
  • 原文地址:https://www.cnblogs.com/waryan/p/13837674.html
Copyright © 2020-2023  润新知