luogu 4234 最小差值生成树 LCT

news/2024/11/21 1:47:22/

感觉码力严重下降~

#include <bits/stdc++.h>  
#define N 400006 
#define inf 1000000000     
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std; 
multiset<int>S;    
multiset<int>::iterator it;         
struct Edge 
{int u,v,c; Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c){}  
}e[N];
bool cmp(Edge a,Edge b) 
{return a.c<b.c;    
}   
struct Union
{int p[N];  void init() {for(int i=1;i<N;++i) p[i]=i; } int find(int x) {return p[x]==x?x:p[x]=find(p[x]);     }int merge(int x,int y) {x=find(x),y=find(y); if(x!=y) {p[x]=y; return 1; } return 0;            }
}ufs;    
struct Link_Cut_Tree
{          #define lson t[x].ch[0] #define rson t[x].ch[1]   int sta[N];     struct Node {      int ch[2],f,min,id,val,rev;                          }t[N];   int isrt(int x) {return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x);       }int get(int x)                     {return t[t[x].f].ch[1]==x; }   void pushup(int x) {     t[x].min=t[x].val, t[x].id=x;     if(lson && t[lson].min<t[x].min) t[x].min=t[lson].min,t[x].id=t[lson].id;   if(rson && t[rson].min<t[x].min) t[x].min=t[rson].min,t[x].id=t[rson].id;    } void mark(int x) { if(x) t[x].rev^=1,swap(lson,rson);     }void pushdown(int x) {   if(t[x].rev) {if(lson) mark(lson); if(rson) mark(rson); t[x].rev=0;          }}void rotate(int x) {int old=t[x].f,fold=t[old].f,which=get(x);   if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x;     t[old].ch[which]=t[x].ch[which^1], t[t[old].ch[which]].f=old;  t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold;       pushup(old),pushup(x);       }    void splay(int x) {int v=0,u=x,fa;            for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f;      for(;v;--v) pushdown(sta[v]);                          for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) if(t[fa].f!=u) rotate(get(fa)==get(x)?fa:x);          }void Access(int x) {for(int y=0;x;y=x,x=t[x].f) splay(x),rson=y,pushup(x);       }void makeroot(int x) {Access(x),splay(x),mark(x);    }   void link(int x,int y) {makeroot(x),t[x].f=y;      }   void cut(int x,int y) {makeroot(x),Access(y),splay(y);   t[t[y].ch[0]].f=0;   t[y].ch[0]=0;    pushup(y);       }   void split(int x,int y) {makeroot(x),Access(y),splay(y);      }#undef lson #undef rson 
}op;   
int main() 
{ int i,j,n,m,ans=inf;    // setIO("input");           scanf("%d%d",&n,&m);     for(i=1;i<=m;++i) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].c);    sort(e+1,e+1+m,cmp);     ufs.init();   for(i=1;i<=n;++i) op.t[i].val=inf;          for(i=1;i<=m;++i) { int x=e[i].u,y=e[i].v,c=e[i].c,_new=i+n;  if(x==y) continue;    if(ufs.merge(x,y)) {    op.t[_new].val=c;       op.link(x,_new);   op.link(_new,y);   S.insert(c);       } else{op.split(x,y);    if(op.t[y].min<c)                                                   { S.erase(S.find(op.t[y].min));       S.insert(c);                                           int kk=op.t[y].id;                                int xx=e[kk-n].u;       int yy=e[kk-n].v;       op.cut(xx,kk);  op.cut(yy,kk);    op.t[_new].val=c;              op.link(x,_new);  op.link(_new,y);   }}  if(S.size()>=n-1) {it=S.end();    it--;  ans=min(ans,*(it)-*(S.begin()));              }}     printf("%d\n",ans);    return 0; 
}

  

转载于:https://www.cnblogs.com/guangheli/p/11580745.html


http://www.ppmy.cn/news/356264.html

相关文章

洛谷P4234 最小差值生成树

LCT维护生成树 把边从小到大排序&#xff0c;然后一条一条加边&#xff0c;如果成环就把环上最小的删了&#xff0c;我们得到的第一个生成树就是最小生成树。 然后之后每一条边都比前面的生成树的最大边大&#xff0c;我们用这条边的权值减去生成树里最小的&#xff0c;更新答案…

洛谷 P4234 LCT + 排序 + 枚举

求边权最大值与最小值的差值最小的生成树&#xff0c;输出这个差值大小。 按权值排序&#xff0c;我们等同于枚举最大值&#xff0c;然后更新生成树让生成树的最小值尽可能最大。 也就是每次加入边&#xff0c;若构成环&#xff0c;则去掉环上最小值。 若加入边不会构成环&…

LuoguP4234_最小差值生成树_LCT

LuoguP4234_最小差值生成树_LCT 题意&#xff1a; 给出一个无向图&#xff0c;求最大的边权减最小的边权最小的一棵生成树。 分析&#xff1a; 可以把边权从大到小排序&#xff0c;然后类似魔法森林那样插入。 如果两点不连通&#xff0c;直接连上&#xff0c;否则找到两点间最…

NKOJ 4234 三角分形

问题描述 今天何老板得到了一个神奇的正三角形&#xff0c;它具有自动分形技能。 一天后&#xff0c;它会分成4个相同的正三角形&#xff0c;其中三个“尖尖”朝上&#xff0c;一个“尖尖”朝下。 一天后&#xff0c;里面的每个三角形又会按上述规则分形下去。 如此反复………

[luogu4234]最小差值生成树

[luogu4234]最小差值生成树 luogu 从小到大枚举边,并连接,如果已连通就删掉路径上最小边 lct维护\(ansmin(E_{max}-E_{min})\) #include<bits/stdc.h> using namespace std; const int _4e55; int re(){int x0,w1;char chgetchar();while(ch<0||ch>9){if(ch-)w-1;c…

HDU 4234 Moving Points

刚开始做的时候还以为是暴搜&#xff0c;YY了各种剪枝&#xff0c;结果华丽丽的TLE了 正解&#xff1a; 状态压缩DP dp[当前走到的点][状态] 状态&#xff1a; 第i位表示第i个点有没有被消灭 转移&#xff1a; 详见代码 注意&#xff1a; 计算转移cost时要用O(1) 的算法 二分…

4234最小差值生成树

有点巧妙啊&#xff01; s[x]每次维护的是最小值 我们将边按从大到小排个序,这样编号小的就在前面啦&#xff01;QAQ 再按最小生成树的LCT的做法来 不过我们每次要用一个book标记前面最小边的编号 每次要更新答案时&#xff0c;一直往前跳&#xff0c;跳到最晚更新的即使最小的…

洛谷.4234.最小差值生成树(LCT)

题目链接 先将边排序&#xff0c;这样就可以按从小到大的顺序维护生成树&#xff0c;枚举到一条未连通的边就连上&#xff0c;已连通则(用当前更大的)替换掉路径上最小的边&#xff0c;这样一定不会更差。 每次构成树时更新答案。答案就是当前边减去生成树上最小边的权值。 LCT…