[Luo Gu P4172] WC2006 pipes Secretary

Problem Description

SC MY province city has a huge network of underground pipes, water pipes Secretary MY toot City (water pipe is the pipe anyway), is toot work as director of water: water company every day may want to send a certain amount of water from at x to y, the toot need to find a path from a to B in the water supply pipe company, then notifies the pipe water supply path into the preparation state by the control center of the information on each path until the water are ready, water the company can start a bottled water. Toot can only handle one task bottled water, bottled water until the current task is completed, in order to deal with the next one.

Prior to processing each task and bottled water, the water on the path to be a series of preparatory operations, such as cleaning, disinfecting and so on. Beep at the control center order, these pipe preparation operation started simultaneously, but since the length of the pieces of pipe, different internal diameters, the time required to perform preparatory operations may differ. Water companies always want to toot water to find such a path, all the pipes on the path all the time needed to ready as short as possible. Dudu hope you can help him to complete such a system a choice of paths to meet the water requirements of the company. In addition, due to the city's water pipes MY age, some of the water from time to time lead to failure can not be used, your program must take this into account.

City water pipe may wish to MY network as a simple undirected graph (i.e., not from edge ring or weight): water is the edges in the graph, the pipe is connected to the node of FIG.

Input Format

Behavior file input to the first three integers: N, M, Q represent the number of pipe connections (nodes), the water current (non-directed edges) number, and the number of tasks to be processed your program (including the search for a satisfying and paths required to accept the fact that a broken water pipe article).

The following M rows, each row of three integers x, y, and t, corresponding to a water pipe described. x and y represent numbers across the junction of the pipe, t represents the time required to prepare water supply. We wish to node numbers from 1 to N, so that all x and y are in the range [1, N].

The following Q lines, each line describes one task. Wherein the first integer k: if k = 1 then followed by two integers A and B, that you need to look for water path from A to B to satisfy the requirements for a water companies; if k = 2, then followed by two integers x and y, represents a direct water connection x and y to be rejected (legal guarantee, that before this direct connection x and y have not yet scrapped pipe must exist).

Output Format

Sequence corresponding to each of the input file a task k = 1, you need to output a digital and a carriage return / line feed. The numbers indicate: Do you find the path to the water pipes all the time to complete all the preparatory work required (of course, requires a minimum).

Sample input

4 4 3
1 2 2
2 3 3
3 4 2
1 4 2
1 1 4
2 1 4
1 1 4

Sample Output

2
3

data range

≤ 1000 N
M ≤ 100000
Q ≤ 100000
test data to be rejected pipes not more than 5000; and at any time we consider water pipe network is connected.

Resolve

Analyze the title of model. Assuming no border erase operation, then the minimum to maintain the maximum value between two points on the path, it can be done with a minimum spanning tree. But when added after the border erase operation, the minimum spanning tree becomes a dynamic. yy look, which seem to be using LCT do. Then the maintenance side of the maximum value of the minimum spanning tree with LCT. Considering the Border Erase operation is not good (deleted even after the reconstruction in order to maintain the spanning tree), we might think upside down, the minimum spanning tree of final status is determined, then the border erase operation as a plus side, each addition edge \ ((u, v) \) when, regarded among the (u, v) with a maximum weight of added side comparison, if the maximum value is greater than the weight, then delete after adding new maximum side edge ,, otherwise, do nothing. You can look directly when asked.

However, it is still difficult to achieve. LCT because maintenance is a point, and here is the requirement edge. Therefore, we point to the edge of the right side becomes the right point. When implemented, the map may be mapped to an edge point of a number to achieve.

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <map>
#define N 1000002
using namespace std;
struct edge{
    int u,v,w;
}e[N];
struct task{
    int op,x,y,id;
}a[N];
int n,m,q,i,son[N][2],fa[N],val[N],dat[N],f[N],s[N],ans[N];
bool r[N],del[N];
map<pair<int,int>,int> id;
bool unroot(int x)
{
    return son[fa[x]][0]==x||son[fa[x]][1]==x;
}
void flip(int x)
{
    swap(son[x][0],son[x][1]);
    r[x]^=1;
}
void update(int x)
{
    dat[x]=val[x];
    if(e[dat[son[x][0]]].w>e[dat[x]].w) dat[x]=dat[son[x][0]];
    if(e[dat[son[x][1]]].w>e[dat[x]].w) dat[x]=dat[son[x][1]];
}
void spread(int x)
{
    if(r[x]){
        r[x]=0;
        if(son[x][0]) flip(son[x][0]);
        if(son[x][1]) flip(son[x][1]);
    }
}
void rotate(int x)
{
    int y=fa[x],z=fa[y],p=(son[y][1]==x),w=son[x][p^1];
    if(unroot(y)) son[z][son[z][1]==y]=x;
    son[x][p^1]=y;son[y][p]=w;
    if(w) fa[w]=y;
    fa[y]=x;fa[x]=z;
    update(y);
}
void splay(int x)
{
    int y=x,z,top=0;
    s[++top]=y;
    while(unroot(y)) s[++top]=y=fa[y];
    while(top) spread(s[top--]);
    while(unroot(x)){
        y=fa[x];z=fa[y];
        if(unroot(y)) rotate((son[y][1]==x)^(son[z][1]==y)?x:y);
        rotate(x);
    }
    update(x);
}
void access(int x)
{
    for(int y=0;x;y=x,x=fa[x]){
        splay(x);
        son[x][1]=y;
        update(x);
    }
}
void makeroot(int x)
{
    access(x);splay(x);
    flip(x);
}
int findroot(int x)
{
    access(x);splay(x);
    while(son[x][0]) update(x),x=son[x][0];
    splay(x);
    return x;
}
void split(int x,int y)
{
    makeroot(x);
    access(y);splay(y);
}
void link(int x,int y)
{
    makeroot(x);
    if(findroot(y)!=x) fa[x]=y;
}
void cut(int x,int y)
{
    makeroot(x);
    if(findroot(y)==x&&fa[y]==x&&!son[y][0]){
        fa[y]=son[x][1]=0;
        update(x);
    }
}
int my_comp(const edge &x,const edge &y)
{
    return x.w<y.w;
}
int find(int x)
{
    if(f[x]!=x) f[x]=find(f[x]);
    return f[x];
}
void Kruscal()
{
    int cnt=n;
    for(int i=1;i<=n;i++) f[i]=i;
    for(int i=1;i<=m;i++){
        if(cnt==1) break;
        if(!del[i]){
            int f1=find(e[i].u),f2=find(e[i].v);
            if(f1!=f2){
                f[f1]=f2;
                link(e[i].u,i+n);link(e[i].v,i+n);
                cnt--;
            }
        }
    }
}
int main()
{
    cin>>n>>m>>q;
    for(i=1;i<=m;i++){
        cin>>e[i].u>>e[i].v>>e[i].w;
        if(e[i].u>e[i].v) swap(e[i].u,e[i].v);
    }
    sort(e+1,e+m+1,my_comp);
    for(i=1;i<=m;i++) id[make_pair(e[i].u,e[i].v)]=i;
    for(i=1;i<=q;i++){
        cin>>a[i].op>>a[i].x>>a[i].y;
        if(a[i].x>a[i].y) swap(a[i].x,a[i].y);
        if(a[i].op==2){
            int tmp=id[make_pair(a[i].x,a[i].y)];
            a[i].id=tmp;
            del[tmp]=1;
        }
    }
    for(i=1;i<=n+m;i++){
        if(i>n) val[i]=dat[i]=i-n;
    }
    Kruscal();
    for(i=q;i>=1;i--){
        if(a[i].op==1){
            split(a[i].x,a[i].y);
            ans[i]=e[dat[a[i].y]].w;
        }
        else{
            split(a[i].x,a[i].y);
            int id=a[i].id,tmp=dat[a[i].y];
            if(e[id].w<e[tmp].w){
                cut(e[tmp].u,tmp+n);cut(e[tmp].v,tmp+n);
                link(a[i].x,id+n);link(a[i].y,id+n);
            }
        }
    }
    for(i=1;i<=q;i++){
        if(a[i].op==1) cout<<ans[i]<<endl;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/10986329.html