2594: [Wc2006] Secretary of water pipe data reinforced version
Time limit:25 Sec Memory limit:128 MB
submit:2560 solved:820
Description
SC province My city has a huge network of underground water pipe, toot is my city's water pipe director (is pipe water), doodle as the water pipe Secretary's work is: every day water company may be to send a quantity of water from X to Y, toot need for water company to find a from a to B water pipe path, Then through the information of the control center to inform the path of the water pipe into the ready to send the state, until the path of each water pipe are ready, the water supply company can start to send water. Doodle can only handle one water delivery task at a time, until the current water delivery task is completed, to deal with the next item.
Before handling each water delivery task, the water pipes on the path are prepared for a series of preparations, such as cleaning, disinfection and so on. Dudu in the control center commanded, these water pipe preparation operations started at the same time, but due to the length of each pipe, the inner diameter is different, the time required to prepare the operation may be different. Water companies always want to doodle to find such a water supply path, all the pipelines on the path are ready for the shortest possible time. Dudu wants you to help him complete such a path-selecting system to meet the requirements of the water supply company. In addition, due to the old water pipes in my city, some of the water pipes will occasionally fail to use, your program must take this into account.
Think of my city's plumbing network as a simple, non-circular diagram (i.e. no self-loops or heavy edges): The water pipe is the side of the diagram and the junction of the water pipe is the node in the diagram.
Input
Input file first behavior 3 integers: N, M, q indicate the number of pipe connections (nodes), the number of current water pipes (no edge), and the number of tasks your program needs to handle (including finding a path to meet the requirements and accepting the fact that a pipe is broken).
The following m lines, each line 3 integers x, y and T, describe a corresponding water pipe. X and Y indicate the number of nodes on both ends of the pipe, and T indicates the time required to prepare the water for delivery. We might as well number the nodes from 1 to n so that all x and Y are within the range [1, n].
The following q lines, each line describes a task. Where the first integer is K: if K=1 is followed by two integers a and B, you need to find a water supply company to meet the requirements from A to B of the water pipe path, if k=2, followed by two integers x and Y, indicating direct connection x and y of the water pipe declared scrap (Guaranteed legal, That is, before this direct connection x and Y are not scrapped water pipes must exist).
Output
In order to correspond to each k=1 task in the input file, you need to output a number and a carriage return/line feed. The number says: All the pipes in the plumbing path you are looking for are all the time required to complete the preparation (and of course the shortest).
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 of the original problem"
n≤1000
m≤100000
q≤100000
No more than 5,000 pipes were declared scrapped in the test data, and at any time the plumbing network we were considering was connected, that is, from any node A there must be at least one water pipe path leading to either Node B.
"Enhanced data Range"
n≤100000
m≤1000000
q≤100000
Any time we consider the plumbing network is connected, that is, from any node A must have at least one water pipe path to any node B.
"Attention to C + + players"
Because the input size is large (the maximum test point is about 20MB), it can take more time to read into the data using scanf.
Processing edge Weights class LCT can treat the edges as a point and then connect the two points of the edge respectively.
Then maintain a path on the maximum and its position can be used to find the edge, because it can not delete edges, so to do, offline processing.
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath > #include <vector> #include <queue> #include <stack> #include <map> #include <set> #
include<string> #include <iomanip> #include <ctime> #include <climits> #include <cctype>
#include <algorithm> #ifdef WIN32 #define AUTO "%i64d" #else #define AUTO "%lld" #endif using namespace std;
inline void read (int &x) {x=0;
int flag=1;
Char Ch=getchar ();
while (ch< ' 0 ' | | ch> ' 9 ') {if (ch== '-') flag=-1;
Ch=getchar ();
} while (ch>= ' 0 ' && ch<= ' 9 ') {x*=10; x+=ch-' 0 ';
Ch=getchar ();
} X*=flag;
} inline void readout (int x) {if (!x) {Putchar (' 0 '); putchar (' \ n ');
Return
} Char ans[15];
int pos=0;
while (x) {ans[++pos]=x%10+ ' 0 ';
x/=10;
} while (POS) Putchar (ans[pos--]); Putchar (' \ n '); } #define SMAX (x,tmp) X=max (x), (TMP) #define SMIN (x,tmp) X=min ((x), (TMP)) #define MAXX (X1,X2,X3) Max (Max (X1,X2), x3) #
Define MINN (x1,x2,x3) min (min (x1,x2), x3) const int inf=0x3f3f3f3f;
const int MAXN = 100005;
const int MAXM = 1000005;
struct Node {int fa;
int ch[2];
BOOL IsRoot;
int rev;
int mx,id;
int Val,orig; }node[maxn<<2];
Count the nodes,edges for MST, and edges added later int maxnode; #define FA (x) NODE[X].FA #define CH (x,d) node[x].ch[d] #define ISROOT (x) node[x].isroot #define REV (x) Node[x].rev #define MX (x) node[x].mx #define ID (x) node[x].id #define VAL (x) node[x].val #define ORIG (x) node[x].orig inline void update (int
x) {if (!x) return; MX (x) =val (x);
ID (x) =orig (x);
if (CH (x,0) && mx (CH (x,0)) >mx (x)) MX (x) =mx (CH (x,0)), ID (x) =id (CH (x,0));
if (CH (x,1) && mx (CH (x,1)) >mx (x)) MX (x) =mx (CH (x,1)), ID (x) =id (CH (x,1));
} inline void rotate (int x) {int Y=FA (x), Z=fa (y);
int l= (CH (y,1) ==x), r=l^1; if (IsRoot (y)) isroot (y) =false,isroot (x) =true;
else Ch (z,ch (z,1) ==y) =x; FA (CH (x,r)) =y; FA (y) =x;
FA (x) =z; CH (y,l) =ch (x,r);
CH (x,r) =y; Update (y);
Update (x);
} inline void pushdown (int x) {if (!x) return;
if (!rev (x)) return; Rev (x) ^=1;
Swap (CH (x,0), CH (x,1));
if (CH (x,0)) Rev (Ch (x,0)) ^=1;
if (CH (x,1)) Rev (Ch (x,1)) ^=1;
} int sta[maxn<<1];
int top;
inline void Upgrade (int x) {while (!isroot (x)) Sta[++top]=x,x=fa (x);
Sta[++top]=x;
while (top) pushdown (sta[top--]);
} inline void splay (int x) {upgrade (x);
while (!isroot (x)) {int Y=fa (x), Z=fa (y);
if (!isroot (y)) if (CH (y,0) ==x ^ ch (z,0) ==y) rotate (x);
else rotate (y);
Rotate (x);
}} inline int access (int x) {int y=0;
do {splay (x);
IsRoot (CH (x,1)) =true;
IsRoot (CH (x,1) =y) =false;
Update (x);
X=FA (y=x);
}while (x);
return y; } inline void Makeroot (int x) {int rt=access (x);
Rev (RT) ^=1;
} void Cut (int u,int v) {makeroot (U); Access (v);
Splay (v);
IsRoot (CH (v,0)) =true; FA (CH (v,0)) = 0;
CH (v,0) = 0;
Update (v);
} void Join (int u,int v) {access (U); splay (U);
Rev (U) ^=1;
FA (U) =v;
} inline int Findroot (int x) {while (FA (x)) X=fa (x);
return x;
} inline bool Query_block (int u,int v) {int t1=findroot (u), T2=findroot (v);
return t1==t2;
} int query (int u,int v)//Return the ID of nodes {makeroot (U); Access (v);
Splay (v);
Return ID (v);
} struct Road {int u,v;
int C;
BOOL Flag; BOOL operator < (const Road t) const {return c < t.c;}}
ROAD[MAXM]; struct Fnode {int u,v;}
fnode[maxn<<2];
BOOL CMP (const road X,const Road y) {if (x.u ^ y.u) return x.u < y.u;
return X.V < Y.V; } struct Query {int k,x,y;}
QUE[MAXN];
int n,m,q;
void Kruskal () {int tot=0; for (int i=1;i<=m;i++) if (Road[i].flag) {if (Query_block (ROAD[I].U,ROAD[I].V)) ContinUe
Road Now=road[i]; Node &t=node[++maxnode];
FNODE[MAXNODE].U=NOW.U,FNODE[MAXNODE].V=NOW.V; T.MX=T.VAL=NOW.C;
T.id=t.orig=maxnode;
T.isroot=true;
Join (MAXNODE,NOW.U);
Join (MAXNODE,NOW.V);
if (++tot = = n-1) break;
}} int ANS[MAXN];
int Topp;
int main () {#ifndef Online_judge freopen ("water.in", "R", stdin);
Freopen ("Water.out", "w", stdout);
#endif read (n), read (m), read (q);
for (int i=1;i<=n;i++) isroot (i) =true;
Maxnode=n;
for (int i=1;i<=m;i++) {int u,v,c;
scanf ("%d%d%d", &u,&v,&c);
if (u>v) swap (U,V);
Road[i]= (Road) {u,v,c,true};
} sort (road+1,road+m+1,cmp);
for (int i=1;i<=q;i++) {int k,x,y;
scanf ("%d%d%d", &k,&x,&y);
if (x>y) swap (x, y);
Que[i]= (Query) {k,x,y};
if (k==1) continue; Road T; T.u=x;
T.v=y;
int Pos=lower_bound (ROAD+1,ROAD+M+1,T,CMP)-road; road[Pos].flag=false;
} sort (road+1,road+m+1);
Kruskal ();
Sort (road+1,road+m+1,cmp);
for (int i=q;i>=1;i--) if (que[i].k==1) ans[++topp]=val (query (QUE[I].X,QUE[I].Y));
else {Road tt= (road) {QUE[I].X,QUE[I].Y};
int Pos=lower_bound (ROAD+1,ROAD+M+1,TT,CMP)-road;
int Tmp=query (QUE[I].X,QUE[I].Y);
if (Val (TMP) <ROAD[POS].C) continue; Cut (TMP,FNODE[TMP].U);
Cut (TMP,FNODE[TMP].V); Node &t=node[++maxnode];
FNODE[MAXNODE].U=QUE[I].X,FNODE[MAXNODE].V=QUE[I].Y; T.MX=T.VAL=ROAD[POS].C;
T.id=t.orig=maxnode;
T.isroot=true;
Join (maxnode,que[i].x);
Join (MAXNODE,QUE[I].Y);
} while (Topp) readout (ans[topp--]);
return 0;
}