CodeForces - 1243D (thinking + disjoint-set)

The meaning of problems

https://vjudge.net/problem/CodeForces-1243D

There is a complete graph, n nodes

There right side edges m is 1, and the rest are all 0

This will give you m edges

You ask the right value of the minimum spanning tree of this graph

Thinking

The idea is very simple Edges a weight of 0 shrunk configuration of a plurality of communication blocks, the answer is the number of connected blocks -1.

However, too much number of edges, there are n * (n-1) / 2-m edge strip with a weight of zero.

Consider for each point, point to calculate the number of edges connected to its set point is located, with a map memory, and then the corresponding set size (points), and if the former is smaller than the latter, so that this point to the collection as well as the Some edge weight value of 0, so this point may be added to the collection.

Note that when the merger is to think clearly at this point into the current collection, do not write backwards! Otherwise TLE12.

Final answer is the number of connected blocks minus one.

Here we can turn into an undirected graph directed graph, so that each point only to the point of even smaller than its side, so traverse when he only considered a small point than this point, the time savings.

Code

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=200005;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
vector<int> g[N];
int f[N],sz[N];
int find(int x)
{
    if(x==f[x])
        return x;
    return f[x]=find(f[x]);
}
int main ()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        f [i] = i, Sz [i] = 1;
    for(int i=1;i<=m;i++)
    {
        you and, v;
        scanf("%d%d",&u,&v);
        if (u <v) // search ordering
            swap(u,v);
        g[u].push_back(v);
    }
    vector<int> h;
    for(int i=1;i<=n;i++)
    {
        map<int,int> mp;
        for(int j:g[i])
            mp[find(j)]++;
        for(int j:h)
        {
            int fi=find(i),fj=find(j);
            if(fi!=fj&&mp[fj]<sz[fj])
            {
                f [fi] = fj;
                No. [f i] = c + [fi];
            }
        }
        if(find(i)==i)
            h.push_back(i);
    }
    int years = 0;
    for(int i=1;i<=n;i++)
    {
        if(find(i)==i)
            ++ years;
    }
    printf("%d\n",ans-1);
    return 0;
}

  

Guess you like

Origin www.cnblogs.com/mcq1999/p/11983919.html