zoukankan      html  css  js  c++  java
  • FZU 2087 统计树边

    这题第一直觉就是和CF第三次教育场的E题是一样的,

    http://codeforces.com/contest/609/problem/E

    然后直接拉过来代码改了改,提交返回MLE。FZU内存开的小,没救了。

    后来还是同学指教,边总共只有两类,要么存在最少生成树上,要么不属于任何一个最小生成树。

    所以只要按边权从小到大往图中加边,对于相同权值的边,如果两端不在一个集合中,那么答案+1,

    然后再对相同权值的边加入到图中。

    #include <cstdio>
    #include <vector>
    #include <map>
    #include <algorithm>
    using namespace std;
    
    const int maxn=100000+10;
    int fa[maxn];
    
    struct Edge
    {
        int a,b,v;
    }e[maxn];
    vector<Edge>v[1000];
    int n,m;
    
    int Find(int x)
    {
        if(x!=fa[x]) fa[x]=Find(fa[x]);
        return fa[x];
    }
    
    void read()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++) scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].v);
        for(int i=0;i<=500;i++) v[i].clear();
        for(int i=0;i<m;i++) v[e[i].v].push_back(e[i]);
    }
    
    void work()
    {
        int ans=0;
        for(int i=1;i<=500;i++)
        {
            if(v[i].size()==0) continue;
            for(int j=0;j<v[i].size();j++)
            {
                int fu=Find(v[i][j].a);
                int fv=Find(v[i][j].b);
                if(fu!=fv) ans++;
            }
            for(int j=0;j<v[i].size();j++)
            {
                int fu=Find(v[i][j].a);
                int fv=Find(v[i][j].b);
                if(fu!=fv) fa[fu]=fv;
            }
        }
        printf("%d
    ",ans);
    }
    
    void init()
    {
        for(int i=1;i<=n;i++) fa[i]=i;
    }
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            read();
            init();
            work();
        }
        return 0;
    }
  • 相关阅读:
    (转)bash内置命令mapfile:读取文件内容到数组
    new 一个接口?
    Linq的一些操作符图表展示
    StreamReader 和文件乱码
    XSLT 的调试
    不一样的大小写转换
    一些可能没用过的调试窗口
    私人工具分享:博客下载工具
    简单的实例来理解WCF 数据服务
    谈谈char ,nchar,varchar,nvarchar 和Uniqueidentifier
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5242650.html
Copyright © 2011-2022 走看看