zoukankan      html  css  js  c++  java
  • 【HDU 5438】Ponds

    不断删去度数为1的点,最后求有奇数个点的联通块的权值之和。

    分析

    存边的时候,要头尾都存这个边。用dfs或者队列删点,再用并查集或者dfs确定联通块,然后统计联通块的点数,最后累加。

    我自己写的超时,然后参考了网上的题解。真郁闷。

    代码

    并查集

    #include<cstdio>
    #include<queue>
    #include<vector>
    #define ll long long
    
    using namespace std;
    
    const int N = 1e4 + 10;
    
    ll v[N];
    ll s[N];
    int n,m,e[N],f[N],cn[N];
    vector<int> d[N];
    
    int find(int a)
    {
        return f[a]==a?a:find(f[a]);
    }
    
    void unite(int a,int b)
    {
        a=find(a),b=find(b);
        if(a!=b) f[a]=b;
    }
    
    void add(int a,int b)
    {
        e[a]++;
        e[b]++;
        d[a].push_back(b);
        d[b].push_back(a);
        unite(a,b);
    }
    
    void del()
    {
        queue<int>q;
        for(int i=1; i<=n; i++) if(e[i]==1) q.push(i);
        while(!q.empty())
        {
            int r=q.front();
            q.pop();
            for(int j=0; j<d[r].size(); j++)
            {
                int w=d[r][j];
                e[w]--;
                if(e[w]==1)q.push(w);
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
            {
                scanf("%lld",&v[i]);
                e[i]=s[i]=cn[i]=0;
                f[i]=i;
                d[i].clear();
            }
            for(int i=1; i<=m; i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                add(a,b);
            }
            del();
            for(int i=1; i<=n; i++)
            {
                if(e[i]>1)
                {
                    int a=find(i);
                    s[a]+=v[i];
                    cn[a]++;
                }
            }
            ll ans=0;
            for(int i=1; i<=n; i++)
            {
                if (f[i]==i && cn[i]&1)
                {
                    ans+=s[i];
                }
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }

    dfs确定联通块

    #include<cstdio>
    #include<queue>
    #include<vector>
    #define ll long long
    
    using namespace std;
    
    const int N = 1e4 + 10;
    
    ll v[N];
    int n,m,e[N],vis[N];
    ll ct,sum;
    vector<int> d[N];
    
    void add(int a,int b)
    {
        e[a]++;
        e[b]++;
        d[a].push_back(b);
        d[b].push_back(a);
    }
    void dfs(int a)
    {
        vis[a]=1;
        sum+=v[a];
        ct++;
        for(int i=0; i<d[a].size(); i++)
        {
            int w=d[a][i];
            if(!vis[w]) dfs(w);
        }
    }
    void del()
    {
        queue<int>q;
        for(int i=1; i<=n; i++)
        {
            if(e[i]==1) q.push(i);
            if(e[i]==0) vis[i]=1; // 别忘了度为0的点
        }
        while(!q.empty())
        {
            int r=q.front();
            vis[r]=1;
            q.pop();
            for(int j=0; j<d[r].size(); j++)
            {
                int w=d[r][j];
                e[w]--;
                if(e[w]==1)q.push(w);
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            for(int i=1; i<=n; i++)
            {
                scanf("%lld",&v[i]);
                e[i]=vis[i]=0;
                d[i].clear();
            }
            for(int i=1; i<=m; i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                add(a,b);
            }
            del();
            ll ans=0;
            for(int i=1; i<=n; i++)
            {
                sum=ct=0;
                if(!vis[i]) dfs(i);
                if(ct&1)ans+=sum;
            }
            printf("%lld
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    路径不对 导致FileNotFoundError: [WinError 2] 系统找不到指定的文件, 问题解决办法
    pycharm + selenium + python 提示 Unresolved reference 'webdriver' 解决办法
    highstock实现股票分时
    jquery 源码剖析1
    html 其它标签
    html5 基本内容 摘自W3C
    html总结
    web性能 部分
    linux常用命令 3
    linux常用命令 2
  • 原文地址:https://www.cnblogs.com/flipped/p/5223469.html
Copyright © 2011-2022 走看看