Topic links
Topic: Given a tree, there are two operations:
1. Ask the number of the first black edge encountered on the path to the root of a point
2. Apply a path to black
Solution: I wrote a violent procedure according to the train of thought 3910, then the Tle, the film
First, each edge is grouped at the point below it, and each point represents its connection to the father, so that the following actions on the edge are used to represent
All the actions are carried out, and all the neighboring points of the black Edge are merged according to the relationship, so that the represented element in a set must be the least depth point
Backwards to do all the operation, for the dyeing operation to undo the equivalent of dyeing white, according to the time of the edge is dyed black, directly merge each edge, here in order to prioritize the merger from beginning to finish is white edge, the dyeing time is set to M+1
Each time the query operation is directly looking for the representative element of the collection, its represented edge is the answer
My harvest: Strong ah, kneeling AH
TLE
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace
Std
const int m=1000005;
int n,m,t;
int head[m],f[m],fa[m],dep[m],pre[m];
int read () {int X=0,f=1;char c=getchar (); while (c< ' 0 ' | |
C> ' 9 ') {if (c== '-') F=-1;c=getchar ();}
while (c>= ' 0 ' &&c<= ' 9 ') {x=x*10+c-' 0 '; C=getchar ();}
return x*f; } struct Edge{int to,nex,id;}
E[M*4];
void Add (int u,int v) {e[t].to=v,e[t].nex=head[u],head[u]=t++;}
int fid (int x) {return F[x]==x?x:f[x]=fid (f[x]);}
void Uniom (int x,int y) {int p=fid (x), Q=fid (y), if (p!=q) f[x]=y;}
void Dfs (int x) {for (int i=head[x];i!=-1;i=e[i].nex) {int v=e[i].to;
if (V!=fa[x]) Pre[v]=i,fa[v]=x,dep[v]=dep[x]+1,dfs (v);
}} int query (int x) {while (FID (x)!=fid (1)) x=fa[x];
if (x==1) return 0;
Return (pre[x]+1)/2;
} void Change (int. P,int Q) {while (FID (p)!=fid (q)) {if (Dep[p]<dep[q]) swap (P,Q);
F[P]=F[FA[P]],P=F[P]; }} void Work () {int opt,x,y;
while (m--) {scanf ("%d", &opt);
if (opt==1) X=read (), printf ("%d\n", query (x));
if (opt==2) X=read (), Y=read (), change (x, y);
}} void init () {int x, y;
Cin>>n>>m;t=1;memset (head,-1,sizeof (head));
for (int i=1;i<n;i++) X=read (), Y=read (), add (x, y), add (y,x);
for (int i=1;i<=n;i++) f[i]=i;
DFS (1);
} int main () {init ();
Work ();
return 0; }
AC
#include <iostream> #include <cstdio> #include <cstring> using namespace std;
#define M 1000010 int n,m,t,now;
int f[m],sum[m],be[m],p[m],vl[m];
int head[m],pre[m],fa[m],dep[m]; struct Edge{int to,nex,id;}
E[M*4];
void Add (int u,int v,int z) {e[t]= (edge) {v,head[u],z};head[u]=t++;}
int Find (int x) {return f[x]==x?x:f[x]=find (f[x]);}
void Dfs (int x,int father) {for (int i=head[x];i!=-1;i=e[i].nex) {int v=e[i].to;
if (v==father) continue;
pre[v]=e[i].id,fa[v]=x,dep[v]=dep[x]+1;
DFS (V,X);
}} void up (int x,int y,int k) {//is in the merging operation, here is the point X=find (x), Y=find (y);
while (x!=y) {if (Dep[x]<dep[y]) swap (x, y);
if (be[x]!=m+1) x=f[x];
else be[x]=k,f[x]=f[fa[x]],x=f[x]; }} void Work () {for (int i=1;i<=n;i++) sum[be[i]]++;//to Be[i] cardinality sort for (int i=2;i<=m+1;i++) sum[i]+=sum[i-1]
;
for (int i=1;i<=n;i++) Vl[sum[be[i]]--]=i;//vl[i] represents the number of the first dyed points for (int i=1;i<=n;i++) f[i]=i; For(int i=m+1;i>=1;i--)
{//Reverse processing t=i dyeing, white edge as T=m+1 if (p[i]!=-1) P[i]=pre[find (P[i])];
else for (int x;be[x=vl[now]]==i&&now;now--) f[x]=f[fa[x]];
} for (int i=1;i<=m;i++) if (p[i]!=-1) printf ("%d\n", P[i]);
} void init () {int x,y,opt;
T=0;memset (head,-1,sizeof (head));
scanf ("%d%d", &n,&m); now=n; for (int i=1;i<n;i++) scanf ("%d%d", &x,&y), add (X,y,i), add (y,x,i);//record number for (int i=1;i<=n;i++) f[i]=i,be
[I]=m+1;//be[i] Indicates that the point I represents the edge of the dyed black time Dfs (1,0); memset (P,-1,sizeof (p));
for (int i=1;i<=m;i++) {scanf ("%d", &opt);
if (opt==2) scanf ("%d%d", &x,&y), Up (x,y,i);
Else scanf ("%d", &x), p[i]=x;//p[i] denotes the point of the I-action query}} int main () {init ();
Work ();
return 0; }