Timus Online Judge 2055. Urban Geography Division, can be traced back and set,

Source: Internet
Author: User
Tags joins time limit

2055. Urban GeographyTime limit:2.0 Second
Memory limit:128 MB
Android Vasya prepares a project in Urban geography. The aim of the project is to improve the infrasructure of the city he lives in. Now the city consists of  n districts, some of which is connected by roads. Using These roads one can get from any district to any other district of the city by car. Vasya thinks that such big amount of roads makes citizens use their own cars instead of walking or cycling. He wants to close as many roads for cars as possible and turn them into boulevards. Of course, Vasya wants to keep the possibility to get from any district to any other district of the city by car using Roa Ds. Now citizens pay for using roads, and prices for different roads may vary very much. Vasya thinks that leaving open some expensive and some cheap roads at the same time isn't a good idea beacuse it can incr Ease social tension in the city. That's why he wants-minimize the price spread between the most expensive and the cheapest roads. Help Vasya choose the roads toKeep open. InputThe first line contains integers nиm is the number of the city districts and roads correspondingly (2≤n≤50 000; N−1≤m≤50 000). The next m lines contain triples of integers a I, b i and c I, meaning that between the city districts a I and b i t  Here are a road with the price c I (1≤a I, b i≤n; a i≠b i; 1≤c i≤10 9). There can several roads between, districts.OutputThe only line output the sequence of integers-numbers of the roads which should is kept open in the city. The roads is numbered as they appear in the input data. If There is several solutions, output any of them.Samples

input Output
3 3
1 2 1
2 3 3
3 1 4
2 3
4 5
1 2 1
2 3 1
1 3 2
1 4 2
2 4 1
1 2 5

The lct,t was written before. Learn about the magical use of the DSU, which can be traced back and set.

http://codeforces.com/blog/entry/17579 This is the CF on the post, explained.

The main ztl to explain to me. I've seen the code of a certain course before. ~~2015 Multi-school problem is also the DSU.


Let's talk about persistence and look up the set:

If you have path compression, you cannot implement persistence because the information is overwritten.

Then you can only combine and look up the set in a heuristic way:

1. Do not do path compression, define Fa[u] represents the father of U, R (U) represents the root of the U and check set, Size[u], indicating the number of points in the set with the root of U

2. For the side that joins the U,v, look at R (U), and R (v). If

2.1 size[r (U)] > Size[r (v)] so Fa[r (v)] = R (u), Size[r (u)] + = Size[r (v)]

2.2 Otherwise swap u,v for 2.2 operation

Analysis: Because of the large-scale point as the root, then the deepest depth of the check set is log, without path compression can also be found in the log time root

Can be rolled back, if the O1,o2,o3 sequence is performed and the merge operation is done, then it is rolled back in o3,o2,o1 order.

You can revert back to the original and check the state of the set.

With this nature, the ability to persist and check the set can be achieved through the persistence of the segment tree.


Next, the solution:

For each edge set join time and delete time, to achieve the division, time range of 0-m

1. Sort the edges by small to large

2. Two min. max edge-minimum side value mid

2.1 Record the time range for each edge, the range is start time = own position, end time = Edge Right <= the rightmost position of the edge of the Benquan +mid of the current edge

2.2 Divide (L,r,low,high) means to handle the edges within the L,r interval (the bounds of the edge may be adjusted to handle r-l+1 edges)

The effective time range of the edge is between Low,high

2.3 If an edge is valid for Low,high, then add the edge and check the focus

2.4 If there are only 1 sets of the set, return a solution

2.5 x = (Low+high)/2 If a side time point coincides with the low,x interval into the left recursive processing

2.6 If the left recursive processing has a solution to return a solution

2.7 Right recursion as 2.5,2.6 consistent

2.8 Delete The edge of this join and check set

See the code in detail:




#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <
Vector> using namespace std;
#define MAXN 70005 int FA[MAXN],SIZE[MAXN];
    int find (int u) {///and find root if (fa[u] = = u) return u;
Return find (Fa[u]);
    } int stack[maxn],ans[maxn],top;//stack records which subtree is merged into to make a tree void set_union (int u,int v,int e) {u = find (u), V = find (v);
    if (U = = v) return;
    if (Size[u] < size[v]) swap (U,V);
    Size[u] + = size[v];//Merge two and check sets, and record the contents of the operation, as well as the added edge fa[v] = u;
    Stack[top] = v;
ans[top++] = e;
    } void Live_apart (int u) {//separate two and check set int f = Fa[u];
    SIZE[F]-= Size[u];
Fa[u] = u;
} struct edge{int u,v,w,be,en,id;};
Edge EDGE[MAXN];

int comp (Edge A,edge b) {return A.W < B.W;}
int ID1[MAXN],ID2[MAXN];
int n,m;
    int Fenzhi (int l,int r,int Low,int high) {if (L > R) return 0;
    int ss = Top;
    int l,r,rp=r,u;
        for (l=l;l<=rp;l++) {//Full coverage Low,high The edge of the time range directly joins and sets, u = id1[l]; if (edge[u].be <=Low && edge[u].en >= high) {swap (id1[l--],id1[rp--]);
        Set_union (Edge[u].u,edge[u].v,u);

    }} if (top = = n-1) return 1; int mid = (Low+high)/2;//filters out the Edge for (r=rp,l=l;l<=r;l++) if (edge[id1[l]].be > mid) swap that can enter left recursion (i
    d1[l--],id1[r--]);

    if (Fenzhi (L,l-1,low,mid)) return 1;
    for (r=rp,l=l;l<=r;l++)//filter out the edge if (Edge[id1[l]].en <= mid) swap (id1[l--],id1[r--]) that can enter right recursion;

    if (Fenzhi (L,l-1,mid+1,high)) return 1;
    while (Top > SS)//fallback and check set operation Live_apart (Stack[--top]);
return 0;
            } int work (int mid) {to (int i = 0,j=0;i<m;i++) {while (J&LT;M&AMP;&AMP;EDGE[J].W-EDGE[I].W <= mid)
        j + +;
        edge[i].be = i;
        Edge[i].en = j-1;
    Id1[i] = i;
    } for (int i = 0;i <= n; i++) size[i] = 1,fa[i] = i;
    top = 0;
Return Fenzhi (0,m-1,0,m-1);
    } int main () {scanf ("%d%d", &n,&m);
 for (int i = 0;i < m; i++) {       scanf ("%d%d%d", &AMP;EDGE[I].U,&AMP;EDGE[I].V,&AMP;EDGE[I].W);
    Edge[i].id = i+1;
    } sort (Edge,edge+m,comp);
    int low = 0, high = EDGE[M-1].W-EDGE[0].W;
        while (low <= high) {int mid = (high+low)/2;
        if (Work (mid)) high = mid-1;
    else low = mid+1;
    } work (low);
        for (int i = 0;i < top; i++) {if (I! = 0) printf ("");
    printf ("%d", edge[ans[i]].id);
    } printf ("\ n");
return 0;
 }/* 4 5 1 2 1 2 3 1 1 3 2 1 4 2 2 4 1 3 3 1 2 1 2 3 3 3 1 4 * *


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.