题目链接:https://codeforces.com/contest/1250/problem/N
题意:给定一个图,点从1到1e9,边有2e5,修改一些边,使得最后所有边都在同一集合
题解:由于点比较多,需要离散化;对于每个联通块,把dfs过程中把每个联通块的最后遍历的点以及所在的边进行修改即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=200010;
int n;
struct edge{
int v,nxt,id;
}e[maxn*2];
int head[maxn],tot;
struct node{
int x,y;
}a[maxn];
int b[maxn*2],bn;
int fa[maxn*2];
bool vis[maxn];
int pos,id;
void init(){
tot=0;
for(int i=0;i<=2*n;i++) head[i]=-1,vis[i]=0;//2*n debug了好一会。。
}
void addedge(int u,int v,int id){
e[tot].v=v;e[tot].id=id;
e[tot].nxt=head[u];head[u]=tot++;
}
void dfs(int u,int p){
vis[u]=1;
if(head[u]!=-1){
pos=u;id=e[head[u]].id;
}
for(int i=head[u];~i;i=e[i].nxt){
int v=e[i].v;
if(v==p||vis[v]) continue;
dfs(v,u);
}
return;
}
struct Ans{
int id,fr,to;
}ans[maxn*2];
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
bn=0;
int x,y,u,v;
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
a[i].x=x;a[i].y=y;
b[bn++]=x;b[bn++]=y;
}
sort(b,b+bn);
bn=unique(b,b+bn)-b;//离散化
init();
int mx=0;
for(int i=1;i<=n;i++){
x=a[i].x,y=a[i].y;
//注意这里要使起始点为1
u=lower_bound(b,b+bn,x)-b+1;
v=lower_bound(b,b+bn,y)-b+1;
fa[u]=x;fa[v]=y;
addedge(u,v,i);addedge(v,u,i);
mx=max(mx,max(u,v));
}
dfs(1,1);
int tt=0;
for(int i=2;i<=mx;i++){//《=bn
if(vis[i]) continue;
pos=-1;
dfs(i,i);
if(pos==-1) continue;
ans[tt].id=id;ans[tt].fr=fa[pos];ans[tt++].to=fa[1];
}
printf("%d\n",tt);
for(int i=0;i<tt;i++){
printf("%d %d %d\n",ans[i].id,ans[i].fr,ans[i].to);
}
}
return 0;
}