题目描述

给你一个$n$个点$m$条边的带边权的无向图(无重边,无自环),现在对于每条边,问你这条边的权值最大可以是多大,使得这条边在无向图的所有最小生成树中?(边权都是整数)。


输入格式

第一行包含三个整数$n,m,a$表示点数和边数及特殊性质标记(如果$a=0$表示没有特殊性质,如果殊性质)。
接下来$m$行每行包含三个整数$u,v,w$表示有一条$u$和$v$之间的边,且边权为$w$。


输出格式

输出一行,包含$m$个数,第$i$个数表示第$i$条边对应的答案(如果某条边的权值可以取到$+\infty$输出$-1$)。


样例

样例输入1:

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

样例输出1:

1 1 1 0

样例输入2:

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

样例输出2:

-1 -1 -1


数据范围与提示

特殊性质:$w=1$(对于所有边);
对于所有数据:$1\leqslant u,v\leqslant n,1\leqslant w\leqslant {10}^9$。


题解

对于一条边,分为两种情况:

  $\alpha.$最小生成树上的边,那么它的最大值就是能代替它的最小边的边权$-1$。

  $\beta.$不是最小生成树上的边,那么它的最大值就是最小生成树上那条边的边权$-1$。

对于如何求,用树链剖分就好了,代码稍长……

数据的输出有点问题,如果不在$1$节点的联通块中则输出$0$。

时间复杂度:$\Theta(n\log^2 n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
struct node{int fr,to,w,id;bool tr;}b[100001];
struct rec{int nxt,to,w,id;}e[200001];
int head[70001],cnt;
int maxb,dy[70001];
int n,m,a;
int f[70001];
int depth[70001],size[70001],id[70001],w[70001],son[70001],top[70001],pos[70001],fa[70001];
int trmax[280001],trmin[280001],lz[280001];
int ans[100001];
bool cmp(node a,node b){return a.w<b.w;}
void add(int x,int y,int w,int id)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
e[cnt].id=id;
head[x]=cnt;
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void pre_dfs(int x)
{
size[x]=1;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa[x])
{
depth[e[i].to]=depth[x]+1;
fa[e[i].to]=x;
dy[e[i].to]=e[i].id;
w[e[i].to]=e[i].w;
pre_dfs(e[i].to);
size[x]+=size[e[i].to];
if(size[e[i].to]>size[son[x]])son[x]=e[i].to;
}
}
void pro_dfs(int x,int tp)
{
top[x]=tp;
id[x]=++cnt;
pos[cnt]=x;
if(son[x])pro_dfs(son[x],tp);
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa[x]&&e[i].to!=son[x])pro_dfs(e[i].to,e[i].to);
}
void build(int x,int l,int r)
{
trmin[x]=lz[x]=maxb+1;
if(l==r)
{
trmax[x]=w[pos[l]];
return;
}
int mid=(l+r)>>1;
build(L(x),l,mid);
build(R(x),mid+1,r);
trmax[x]=max(trmax[L(x)],trmax[R(x)]);
}
void pushdown(int x)
{
if(lz[x]==maxb+1)return;
trmin[L(x)]=min(trmin[L(x)],lz[x]);
trmin[R(x)]=min(trmin[R(x)],lz[x]);
lz[L(x)]=min(lz[L(x)],lz[x]);
lz[R(x)]=min(lz[R(x)],lz[x]);
lz[x]=1<<30;
}
int ask(int x,int l,int r,int L,int R)
{
if(R<l||r<L)return 0;
if(L<=l&&r<=R)return trmax[x];
int mid=(l+r)>>1;
return max(ask(L(x),l,mid,L,R),ask(R(x),mid+1,r,L,R));
}
int query(int x,int y)
{
int ret=0;
while(top[x]!=top[y])
{
if(depth[top[x]]<depth[top[y]])swap(x,y);
ret=max(ret,ask(1,1,n,id[top[x]],id[x]));
x=fa[top[x]];
}
if(depth[x]>depth[y])swap(x,y);
if(id[x]<id[y])ret=max(ret,ask(1,1,n,id[x]+1,id[y]));
return ret;
}
void change(int x,int l,int r,int L,int R,int w)
{
if(R<l||r<L)return;
if(L<=l&&r<=R)
{
trmin[x]=min(trmin[x],w);
lz[x]=min(lz[x],w);
return;
}
int mid=(l+r)>>1;
pushdown(x);
change(L(x),l,mid,L,R,w);
change(R(x),mid+1,r,L,R,w);
trmin[x]=min(trmin[L(x)],trmin[R(x)]);
}
int update(int x,int y,int w)
{
int ret=0;
while(top[x]!=top[y])
{
if(depth[top[x]]<depth[top[y]])swap(x,y);
change(1,1,n,id[top[x]],id[x],w);
x=fa[top[x]];
}
if(depth[x]>depth[y])swap(x,y);
if(id[x]<id[y])change(1,1,n,id[x]+1,id[y],w);
return ret;
}
void getans(int x,int l,int r)
{
if(l==r)
{
ans[dy[pos[l]]]=trmin[x];
if(ans[dy[pos[l]]]==maxb+1)ans[dy[pos[l]]]=0;
ans[dy[pos[l]]]--;
return;
}
int mid=(l+r)>>1;
pushdown(x);
getans(L(x),l,mid);
getans(R(x),mid+1,r);
}
int main()
{
scanf("%d%d%d",&n,&m,&a);
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++)
{
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
b[i]=(node){x,y,w,i,0};
maxb=max(maxb,w);
}
sort(b+1,b+m+1,cmp);
for(int i=1;i<=m;i++)
if(find(b[i].fr)!=find(b[i].to))
{
f[find(b[i].fr)]=find(b[i].to);
add(b[i].fr,b[i].to,b[i].w,b[i].id);
add(b[i].to,b[i].fr,b[i].w,b[i].id);
b[i].tr=1;
}
cnt=0;
pre_dfs(1);
pro_dfs(1,1);
build(1,1,n);
for(int i=1;i<=m;i++)
if(!b[i].tr)
{
ans[b[i].id]=query(b[i].fr,b[i].to)-1;
update(b[i].fr,b[i].to,b[i].w);
}
getans(1,1,n);
for(int i=1;i<=m;i++)printf("%d ",ans[i]);
return 0;
}

rp++

[CSP-S模拟测试]:weight(Kruskal+树链剖分)的更多相关文章

  1. NOIP 2013 货车运输【Kruskal + 树链剖分 + 线段树 】【倍增】

    NOIP 2013 货车运输[树链剖分] 树链剖分 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在 ...

  2. 2019.01.20 bzoj2238: Mst(kruskal+树链剖分)

    传送门 树链剖分菜题. 题意简述:给一个无向图,边有边权,每次询问删一条边(对后面的询问无影响)之后的最小生成树. 思路: 先跑一次kruskalkruskalkruskal并把跑出来的最小生成树给链 ...

  3. [CSP-S模拟测试]:party?(霍尔定理+最小割+树链剖分)

    题目描述 $Treeland$国有$n$座城市,其中$1$号城市是首都,这些城市被一些单向高铁线路相连,对于城市$i\neq 1$,有一条线路从$i$到$p_i(p_i<i)$.每条线路都是一样 ...

  4. BZOJ2040[2009国家集训队]拯救Protoss的故乡——模拟费用流+线段树+树链剖分

    题目描述 在星历2012年,星灵英雄Zeratul预测到他所在的Aiur行星在M天后会发生持续性暴雨灾害,尤其是他们的首都.而Zeratul作为星灵族的英雄,当然是要尽自己最大的努力帮助星灵族渡过这场 ...

  5. [HDU3710] Battle Over Cities [树链剖分+线段树+并查集+kruskal+思维]

    题面 一句话题意: 给定一张 N 个点, M 条边的无向连通图, 每条边上有边权 w . 求删去任意一个点后的最小生成树的边权之和. 思路 首先肯定要$kruskal$一下 考虑$MST$里面去掉一个 ...

  6. 【Codeforces827D/CF827D】Best Edge Weight(最小生成树性质+倍增/树链剖分+线段树)

    题目 Codeforces827D 分析 倍增神题--(感谢T*C神犇给我讲qwq) 这道题需要考虑最小生成树的性质.首先随便求出一棵最小生成树,把树边和非树边分开处理. 首先,对于非树边\((u,v ...

  7. [BZOJ2164]采矿【模拟+树链剖分+线段树】

    Online Judge:Bzoj2164 Label:模拟,树链剖分,线段树 题目描述 浩浩荡荡的cg大军发现了一座矿产资源极其丰富的城市,他们打算在这座城市实施新的采矿战略.这个城市可以看成一棵有 ...

  8. jzoj4918. 【GDOI2017模拟12.9】最近公共祖先 (树链剖分+线段树)

    题面 题解 首先,点变黑的过程是不可逆的,黑化了就再也洗不白了 其次,对于\(v\)的祖先\(rt\),\(rt\)能用来更新答案当且仅当\(sz_{rt}>sz_{x}\),其中\(sz\)表 ...

  9. jzoj5987. 【WC2019模拟2019.1.4】仙人掌毒题 (树链剖分+概率期望+容斥)

    题面 题解 又一道全场切的题目我连题目都没看懂--细节真多-- 先考虑怎么维护仙人掌.在线可以用LCT,或者像我代码里先离线,并按时间求出一棵最小生成树(或者一个森林),然后树链剖分.如果一条边不是生 ...

随机推荐

  1. RSA - 原理、特点(加解密及签名验签)及公钥和私钥的生成

    Wiki - RSA加密演算法 Wiki - 欧拉函数 Wiki - 模反元素 ASN.1 格式标准 RSA算法原理(二) 注意: RSA 加密或签名后的结果是不可读的二进制,使用时经常会转为 BAS ...

  2. 机器学习实战笔记-5-Logistic回归

    Logistic回归 优缺点 适用范围 优点:计算代价不高,易于理解和实现. 缺点:容易欠拟合,分类精度可能不高. 适用于:数值型和标称型数据. 仅用于二分类 原理: 每个特征都乘以一个回归系数> ...

  3. 20190818 On Java8 第八章 复用

    第八章 复用 组合语法 初始化引用有四种方法: 当对象被定义时.这意味着它们总是在调用构造函数之前初始化. 在该类的构造函数中. 在实际使用对象之前.这通常称为延迟初始化.在对象创建开销大且不需要每次 ...

  4. python while 循环打印九九乘法表

    方向一 i = 1 while i <= 9: j = 1 while j <= i print('%d*%d = %2d'%( j,i ,i*j),end='') j += 1 prin ...

  5. centos 6.x 配置 mail 发送外部邮件详解和 sendmail 使用简介

    一.mail基本配置 1.配置:vim /etc/mail.rc 在文件末尾追加以下内容: set from=@.com # 别名<123456789@163.com> set smtp= ...

  6. TCL环境检查

    set w [open 1.txt w+] foreach a [info var] { if { [llength [array name $a]]==0 } { puts $w $a:[set $ ...

  7. highcharts.js两种数据绑定方式和异步加载数据的使用

    一,我们先来看看异步加载数据的写法(这是使用MVC的例子) 1>js写法 <script src="~/Scripts/jquery-2.1.4.min.js"> ...

  8. 如何用CSS定义一个动画?

    <style type="text/css"> div{ width:100px;height: 100px; animation: carton 5s; backgr ...

  9. XML处理指令

    “处理指令(PIs)允许文档包含用于应用程序的指令.指令并不是文档字符数据的一部分,但是必须通过应用程序传递”. 处理指令可以用于将信息传递给应用程序.处理指令可以出现在文档任意位置的标记外部.可以出 ...

  10. MySQL数据库使用xtrabackup备份实现小例子

    关于MySQL数据库的备份的工具和方式也比较多,本文只简单介绍一些我司一个平台的备份方案.Xtrabackup是由percona开源的免费数据库热备份软件,但是只能对InnoDB数据库和XtraDB存 ...