Educational Codeforces Round 3 E (609E) Minimum spanning tree for each edge
题意:一个无向图联通中,求包含每条边的最小生成树的值(无自环,无重边)
分析:求出这个图的最小生成树,用最小生成树上的边建图
对于每条边,不外乎两种情况
1:该边就是最小生成树上的边,那么答案显然
2:该边不在最小生成树上,那么进行路径查询,假设加入这条边,那么形成一个环,删去这个环上除该边外的最大权值边,形成一棵树
树的权值即为答案。(并不需要真正加入这条边)
注:其实用树链剖分和LCA都可以,选择自己熟悉的写就行,我写的树链剖分
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn=;
int n,m;
LL mst;
struct Edge
{
int w,v,next;
} edge[maxn<<];
struct E
{
int u,v,w,id,mark;
void init(int a,int b,int c,int d)
{
u=a,v=b,w=c,id=d,mark=;
}
} o[maxn];
bool cmp1(E a,E b)
{
return a.id<b.id;
}
bool cmp2(E a,E b)
{
return a.w<b.w;
}
int head[maxn],p;
void addedge(int u,int v,int w)
{
edge[p].v=v;
edge[p].w=w;
edge[p].next=head[u];
head[u]=p++;
}
int fa[maxn],sz[maxn],id[maxn],dep[maxn],top[maxn],son[maxn],clk;
int ww[maxn],re[maxn];
void dfs1(int u,int f,int d)
{
fa[u]=f;
sz[u]=;
son[u]=-;
dep[u]=d;
for(int i=head[u]; ~i; i=edge[i].next)
{
int v=edge[i].v;
if(v==f)continue;
dfs1(v,u,d+);
sz[u]+=sz[v];
if(son[u]==-||sz[v]>sz[son[u]])
son[u]=v,re[u]=edge[i].w;
}
}
void dfs2(int u,int tp,int cc)
{
id[u]=++clk;
top[u]=tp;
ww[id[u]]=cc;
if(son[u]!=-)dfs2(son[u],tp,re[u]);
for(int i=head[u]; ~i; i=edge[i].next)
{
int v=edge[i].v;
if(v==son[u]||v==fa[u])continue;
dfs2(v,v,edge[i].w);
}
}
int maxw[maxn<<];
void pushup(int rt)
{
maxw[rt]=max(maxw[rt*],maxw[rt*+]);
}
void build(int rt,int l,int r)
{
if(l==r)
{
maxw[rt]=ww[l];
return;
}
int m=(l+r)>>;
build(rt*,l,m);
build(rt*+,m+,r);
pushup(rt);
}
int query(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
return maxw[rt];
int m=(l+r)>>;
int ans=-;
if(x<=m)ans=max(ans,query(rt*,l,m,x,y));
if(y>m)ans=max(ans,query(rt*+,m+,r,x,y));
return ans;
}
int getans(int u,int v)
{
int ans=-;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])swap(u,v);
ans=max(ans,query(,,n,id[top[u]],id[u]));
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans=max(ans,query(,,n,id[son[u]],id[v]));
return ans;
}
int fat[maxn];
int find(int x)
{
if(x==fat[x])return x;
return fat[x]=find(fat[x]);
}
void init()
{
for(int i=; i<=n; ++i)
fat[i]=i;
mst=p=clk=;
memset(head,-,sizeof(head));
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(int i=; i<m; ++i)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
o[i].init(u,v,w,i);
}
sort(o,o+m,cmp2);
int cnt=;
for(int i=; i<m; ++i)
{
int fx=find(o[i].u);
int fy=find(o[i].v);
if(fy==fx)continue;
addedge(o[i].u,o[i].v,o[i].w);
addedge(o[i].v,o[i].u,o[i].w);
cnt++;
o[i].mark=;
fat[fy]=fx;
mst+=o[i].w;
if(cnt>=n-)break;
}
dfs1(,-,);
dfs2(,,);
build(,,n);
sort(o,o+m,cmp1);
for(int i=; i<m; ++i)
{
if(o[i].mark)printf("%I64d\n",mst);
else
{
int tt=getans(o[i].u,o[i].v);
printf("%I64d\n",mst-tt+o[i].w);
}
}
}
return ;
}
Educational Codeforces Round 3 E (609E) Minimum spanning tree for each edge的更多相关文章
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- codeforces 609E Minimum spanning tree for each edge
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- codeforces 609E. Minimum spanning tree for each edge 树链剖分
题目链接 给一个n个节点m条边的树, 每条边有权值, 输出m个数, 每个数代表包含这条边的最小生成树的值. 先将最小生成树求出来, 把树边都标记. 然后对标记的边的两个端点, 我们add(u, v), ...
- cf 609E.Minimum spanning tree for each edge
最小生成树,lca(树链剖分(太难搞,不会写)) 问存在这条边的最小生成树,2种情况.1.这条边在原始最小生成树上.2.加上这条半形成一个环(加上),那么就找原来这条边2端点间的最大边就好(减去).( ...
- Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值
E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...
- Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge 树上倍增
E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST
E. Minimum spanning tree for each edge Connected undirected weighted graph without self-loops and ...
- CF# Educational Codeforces Round 3 E. Minimum spanning tree for each edge
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
随机推荐
- 【BZOJ 2143】 飞飞侠
Description 飞飞国是一个传说中的国度,国家的居民叫做飞飞侠.飞飞国是一个N×M的矩形方阵,每个格子代表一个街区.然而飞飞国是没有交通工具的.飞飞侠完全靠地面的弹射装置来移动.每个街区都装有 ...
- EvnetBus
领域事件(EvnetBus) 文档目录 本节内容: EventBus 注入 IEventBus 获取默认实例 定义事件 预定义事件 处理完异常 实体修改 触发事件 处理事件 处理基类事件 处理程序 ...
- Js setInterval与setTimeout(定时执行与循环执行)的代码(可以传入参数)
最近在做项目时用到了定时执行的js方法,setInterval与setTimeout时间长了不用有些生疏了,所以自己总结了一下,记下来,以便以后使用. Document自带的方法: 循环执行:var ...
- 1194: [HNOI2006]潘多拉的盒子 - BZOJ
Description Input 第一行是一个正整数S,表示宝盒上咒语机的个数,(1≤S≤50).文件以下分为S块,每一块描述一个咒语机,按照咒语机0,咒语机1„„咒语机S-1的顺序描述.每一块的 ...
- Hibernate缓存机制简述 (转)
感谢:http://blog.csdn.net/ramln1989/article/details/5528445 ------------------------------------------ ...
- [转载]Unity3D的断点调试功能
断点调试功能可谓是程序员必备的功能了.Unity3D支持编写js和c#脚本,但很多人可能不知道,其实Unity3D也能对程序进行断点调试的.不过这个断点调试功能只限于使用Unity3D自带的MonoD ...
- Why are very few schools involved in deep learning research? Why are they still hooked on to Bayesian methods?
Why are very few schools involved in deep learning research? Why are they still hooked on to Bayesia ...
- 谈 DevOps 自动化时,也应该考虑到 SOX 等法案
[编者按]作者 Aaron Volkmann 是 CERT Division 高级研究员,在本文中,他对 DevOps 自动化违反 SOX 法案进行了阐述.同时,也简单的提出了如何通过 CI 来避免这 ...
- ajax返回正个页面
- 【无聊放个模板系列】BZOJ 1597 斜率优化
STL 双向队列DEQUE版本 #include<cstdio> #include<cstdlib> #include<cstring> #include<i ...