AtCoder AGC014E Blue and Red Tree (heuristic merge)

Topic Link

https://atcoder.jp/contests/agc014/tasks/agc014_e

answer

Tree cross over on the practice exam did not think that can be retired. . .

First there is a huge said to be difficult to write \ (O (n \ log ^ 3n) \) tree sectional + Tree Tree approach sets:
for each red edge \ ((U, V) \) , two trees to blue path between points \ (1 + \) , and then select a value of each \ (1 \) sides, to find the red edge covering it and then put the \ (1 \) side edged red cut off, then remove the effects of red edge.

Here's positive solutions.
Still above ideas, and then found that the former is assumed broken \ ((i-1) \ ) set Unicom block formed after the Blue edges are \ (B_i \) , even from the \ (I \) section to the second \ (n-\) communication block is formed after the red stripe sets of edges is \ (R_i \) , then the answer is YESif and only if for any \ (2 \ Le I \ Le n-\) , \ (R_i = B_i \) .
Thus obtained may be converted: FIG beginning on which \ (n-\) points \ (2 (n-1) \) edges, two edges overlap when put shrunk connecting two points with a bit, Q last whole can shrink to a point.
Heuristic be merged. Maintaining the current queue weight all sides, and each point adjacent points on all sides of FIG. Each time an edge extracted from the queue, then the edge point is smaller degree of all transferred to a large degree point. So if we can repeat \ ((n-1) \ ) times, the answer is YES, otherwise NO. Adjacent points can be used setto maintain, the top chart can be used mapto maintain.
Time complexity \ (O (n-\ log ^ 2N) \) .

Code

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cassert>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<utility>
#define pii pair<int,int> 
#define mkpr make_pair
using namespace std;

const int N = 1e5;
multiset<int> ae[N+3];
map<pii,int> g;
queue<pii> que;
int n;

void insertedge(int u,int v)
{
    if(u==v) return;
    if(u>v) swap(u,v);
    ae[u].insert(v); ae[v].insert(u);
    g[mkpr(u,v)]++;
    if(g[mkpr(u,v)]==2) {que.push(mkpr(u,v));}
}

void deleteedge(int u,int v)
{
    ae[v].erase(ae[v].find(u));
    if(u>v) swap(u,v);
    if(g.count(mkpr(u,v))) {g.erase(mkpr(u,v));}
}

int main()
{
    scanf("%d",&n);
    for(int i=1; i<=2*(n-1); i++)
    {
        int u,v; scanf("%d%d",&u,&v);
        insertedge(u,v);
    }
    for(int i=1; i<n; i++)
    {
        while(1)
        {
            if(que.empty()) {puts("NO"); return 0;}
            int u = que.front().first,v = que.front().second; que.pop();
            if(!g.count(mkpr(u,v))) {continue;}
            if(ae[u].size()<ae[v].size()) swap(u,v);
            for(set<int>::iterator i=ae[v].begin(); i!=ae[v].end(); i++)
            {
                int x = *i;
                deleteedge(v,x);
                insertedge(u,x);
            }
            break;
        }
    }
    puts("YES");
    return 0;
}

Guess you like

Origin www.cnblogs.com/suncongbo/p/11527505.html