zoukankan      html  css  js  c++  java
  • 「日常训练」Battle Over Cities

    题意与分析

    题意真的很简单,实在不想讲了,简单说下做法吧。
    枚举删除每个点,然后求最小生成树,如果这个路已经存在那么边权就是0,否则按照原来的处理,之后求花费,然后判整个图是否联通(并查集有几个root),如果不联通直接硬点花费是INF,然后处理输出答案即可。
    一道最小生成树的模板题,比较有学习的意义。

    代码

    /*
     * Filename: pat_top_1001.cpp
     * Date: 2018-11-05
     */
    
    #include <bits/stdc++.h>
    
    #define INF 0x3f3f3f3f
    #define PB emplace_back
    #define MP make_pair
    #define fi first
    #define se second
    #define rep(i,a,b) for(repType i=(a); i<=(b); ++i)
    #define per(i,a,b) for(repType i=(a); i>=(b); --i)
    #define ZERO(x) memset(x, 0, sizeof(x))
    #define MS(x,y) memset(x, y, sizeof(x))
    #define ALL(x) (x).begin(), (x).end()
    
    #define QUICKIO                  
        ios::sync_with_stdio(false); 
        cin.tie(0);                  
        cout.tie(0);
    #define DEBUG(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
    
    using namespace std;
    using pi=pair<int,int>;
    using repType=int;
    using ll=long long;
    using ld=long double;
    using ull=unsigned long long;
    
    const int MAXN=505,MAXM=125005;
    int n,m;
    struct Edge
    {
        int u,v,w;
        bool ok;
        Edge(int _u, int _v, int _w, bool _o):
            u(_u), v(_v), w(_w), ok(_o) {}
    };
    vector<Edge> edges;
    vector<int> G[MAXN];
    void add_edge(int u, int v, int w, bool ok)
    {
        edges.PB(u,v,w,ok);
        G[u].PB(int(edges.size())-1);
    }
    
    int edges_ord[MAXM];
    int pa[MAXN];
    int find_pa(int x)
    {
        return pa[x]==x?x:pa[x]=find_pa(pa[x]);
    }
    bool union_pa(int x,int y)
    {
        int fx=find_pa(x),
            fy=find_pa(y);
        if(fx!=fy) pa[fx]=fy;
        else return false;
        return true;
    }
    int kruskal(int nope_pnt)
    {
        int ans=0;
        iota(pa+1, pa+n+1, 1);
        rep(i,0,m-1)
        {
            int u=edges[edges_ord[i]].u,
                v=edges[edges_ord[i]].v,
                w=edges[edges_ord[i]].w;
            bool ok=edges[edges_ord[i]].ok;
            if(u==nope_pnt || v==nope_pnt) continue;
            if(union_pa(u,v))
                ans+=(1-ok)*w;
        }
        int cnt=0;
        rep(i,1,n) if(i!= nope_pnt && find_pa(i)==i)
            cnt++;
        if(cnt==1) return ans;
        else return INF;
    }
    
    int
    main()
    {
        scanf("%d%d", &n,&m);
        rep(i,1,m)
        {
            int u,v,w,o;
            scanf("%d%d%d%d", &u, &v, &w, &o);
            add_edge(u,v,w,o==1);
        }
        iota(edges_ord, edges_ord+m, 0);
        vector<int> ans_pnt;
        int ans_val=0;
        sort(edges_ord, edges_ord+m, [&](int x, int y) -> bool
                                     {
                                         if((1-edges[x].ok)*edges[x].w==
                                            edges[y].w*(1-edges[y].ok))
                                             return (edges[x].u<edges[y].u ||
                                                     (edges[x].u==edges[y].u &&
                                                      edges[x].v<edges[y].v));
                                         else return (1-edges[x].ok)*edges[x].w<
                                             edges[y].w*(1-edges[y].ok);
                                     });
        rep(nope_pnt,1,n)
        {
            int ans_tmp=kruskal(nope_pnt);
            if(ans_tmp>ans_val)
            {
                ans_val=ans_tmp;
                ans_pnt.clear();
                ans_pnt.PB(nope_pnt);
            }
            else if(ans_tmp==ans_val)
                ans_pnt.PB(nope_pnt);
        }
        if(ans_val==0) printf("0");
        else
        {
            rep(i,0,int(ans_pnt.size())-1)
            {
                printf("%d", ans_pnt[i]);
                if(i==int(ans_pnt.size())-1)
                    printf("
    ");
                else printf(" ");
            }
        }
        return 0;
    }
    
    如非注明,原创内容遵循GFDLv1.3发布;其中的代码遵循GPLv3发布。
  • 相关阅读:
    怎样修改原型对象prototype
    怎样获取构造函数的名字
    怎样把实例对象当构造函数用
    怎样理解prototype对象的constructor属性
    怎样理解构造函数的原型对象prototype
    怎样给回调函数绑定this
    怎样绑定this
    怎样理解数组的空元素empty与undefined的区别
    怎样找出数组中的最大数值
    怎样调用对象的原生方法
  • 原文地址:https://www.cnblogs.com/samhx/p/PAT-TOP-1001.html
Copyright © 2011-2022 走看看