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 1877】 [SDOI2009]晨跑
Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...
- MSMQ(消息队列)续
在上一篇我简单介绍了MSMQ的相关概念,本篇将以代码说明 Message Message是MSMQ的数据存储单元,我们的用户数据一般也被填充在Message的body当中,因此很重要,让我们来看一看其 ...
- C#查找子串在原串中出现次数
提供的是一种思路,和具体语言无关. string test = "good good study day day up"; string r = test.Replace(&quo ...
- Flume学习——BasicTransactionSemantics
org.apache.flume.channel.BasicTransactionSemantics An implementation of basic Transaction semantics ...
- 2013流行Python项目汇总
2013流行Python项目汇总 转自:http://www.kankanews.com/ICkengine/archives/102963.shtml Python作为程序员的宠儿,越来越得到人们的 ...
- ADT(android-bundler) HTML EDIT 编辑 xml HTML
逗比的ADT,安装个html一直不成功,最后发现了如下方法 Helper_Install New Software_ http://download.eclipse.org/releases/indi ...
- Java中的try、catch、finally块简单的解析
package com.wangzhu; import java.util.HashMap; import java.util.Map; /** * 在try.catch.finally块中,若try ...
- SQL Server常见问题总结
写在前面 在QQ群,微信群,论坛中经常帮助使用SQL Server数据库的朋友解决问题,但是有一些最常见最基本的问题,每天都有人问,回答多了也不想再解答了,索性把这些问题整理一下,再有人问到直接发链接 ...
- open/write/read
C语言中open函数 作用:打开和创建文件. 简述: 1 2 3 4 #include <fcntl.h> int open(const char *pathname, int flags ...
- ajax返回son数据
JSON 只是一种文本字符串.它被存储在 responseText 属性中 为了读取存储在 responseText 属性中的 JSON 数据,需要根据 JavaScript 的 eval 语句. 函 ...