zoukankan      html  css  js  c++  java
  • hdu-2419 Boring Game

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

    给一个图,预分配点值。随后有三种操作,F u v查询与u联通部分大于等于v的最小的数,没有则返回0,U u v更新u的值为v,E u v删除u-v的边。

    联通块可以用并查集解决,但是删边无法处理。因为没有加边,我们可以把整个操作过程反过来进行,就变成只有加边没有删边了。期间仔细维护各个值就好。

    涉及边的删除,所以用set存边。查找最值可以用multi_set的lower_bound。并查集涉及集合合并,可以用s[a].insert(b.begin(),b.end()),实测效率和遍历b并Insert到a中几乎没差别,切记要让小集合向大集合合并!!!

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <cstdio>
    #include <algorithm>
    #define LL int
    using namespace std;
    const LL N = 20004;
    multiset<int> g[N];
    int n, m, q;
    LL val[N];
    struct cmd
    {
        char e;
        LL k, v;
        cmd(char ee, LL kk, LL vv)
        {
            e = ee;
            k = kk;
            v = vv;
        }
        cmd()
        {
    
        }
    };
    LL pre[N];
    multiset<LL> s[N];
    LL Find(LL x)
    {
        if (pre[x] == x)return x;
        return pre[x]=Find(pre[x]);
    }
    void mix(LL t1, LL t2)
    {
        LL pt1 = Find(t1), pt2 = Find(t2);
        if (pt1==pt2)return;
        if (s[pt1].size() > s[pt2].size()) swap(pt1, pt2);
        pre[pt1] = pt2;
        s[pt2].insert(s[pt1].begin(), s[pt1].end());
        //for (multiset<LL>::iterator it = s[pt1].begin(); it != s[pt1].end(); it++)
            //s[pt2].insert(*it);
        s[pt1].clear();
    }
    void upt(LL nod, LL v)
    {
        LL pt = Find(nod);
        //cout << pt << endl;
        s[pt].erase(s[pt].find(val[nod]));
        val[nod] = v;
        s[pt].insert(v);
    }
    LL fd(LL nod, LL v)
    {
        LL pt = Find(nod);
        multiset<LL>::iterator it= s[pt].lower_bound(v);
        if (it == s[pt].end())return 0;
        return *it;
    }
    cmd v[N * 30];
    int main() {
        int cas = 1;
        while (scanf("%d%d%d",&n,&m,&q)!=EOF)
        {
            for (int i = 1; i <= n; i++)
            {
                LL num;
                s[i].clear();
                g[i].clear();
                scanf("%d", &num);
                val[i] = num;
                pre[i] = i;
            }
            for (int i = 1; i <= m; i++)
            {
                int fr, to;
                scanf("%d%d", &fr, &to);
                g[min(fr,to)].insert(max(fr,to));
                //g[to].insert(fr);
            }
            LL siz = 0;
            while (q--)
            {
                char c[5];
                LL t1, t2;
                scanf("%s %d %d", c, &t1, &t2);
                if (c[0] == 'E')
                {
                    //g[t1].erase(t2);
                    g[min(t1,t2)].erase(g[min(t1,t2)].find(max(t1,t2)));
                }
                if (c[0] == 'U')
                {
                    LL temp = val[t1];
                    val[t1] = t2;
                    t2 = temp;
                }
                v[siz++]=cmd(c[0], t1, t2);
            }
            for (int i = 1; i <= n; i++)s[i].insert(val[i]);
            for (int i = 1; i <= n; i++)
            {
                for (multiset<int>::iterator j = g[i].begin(); j != g[i].end(); j++)
                {
                    int e = *j;
                    mix(i, e);
                }
            }
            LL cnt = 0;
            double ans = 0;
            for (int i = siz-1; i >=0; i--)
            {
                cmd e = v[i];
                //cout << e.e << ": " << e.k <<' '<< e.v << endl;
                if (e.e == 'E')
                {
                    mix(e.k, e.v);
                }
                if (e.e == 'U')
                {
                    upt(e.k, e.v);
                }
                if (e.e == 'F')
                {
                    ans += fd(e.k, e.v);
                    //cout << fd(e.k, e.v) << endl;
                    cnt++;
                }
            }
            printf("Case %d: %.3f
    ", cas++,ans*1.0 / cnt);
        }
    
        return 0;
    }
  • 相关阅读:
    【11.3】
    WPF中内嵌网页的两种方式
    .net的winform中DialogResult属性的使用
    MVC过滤器使用方法
    C#调用C++的DLL错误解决方法
    WPF中UserControl的属性和事件
    React架构之路
    读完这一篇,字符串格式化界的“白富美”(f-strings)抱回家!
    关于使用format()方法格式化字符串,读这一篇就够了!
    String,StringBuffer与StringBuilder
  • 原文地址:https://www.cnblogs.com/LukeStepByStep/p/7453425.html
Copyright © 2011-2022 走看看