题意:一个无向图联通中,求包含每条边的最小生成树的值(无自环,无重边)

分析:求出这个图的最小生成树,用最小生成树上的边建图

对于每条边,不外乎两种情况

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的更多相关文章

  1. [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]

    这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...

  2. 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 ...

  3. codeforces 609E. Minimum spanning tree for each edge 树链剖分

    题目链接 给一个n个节点m条边的树, 每条边有权值, 输出m个数, 每个数代表包含这条边的最小生成树的值. 先将最小生成树求出来, 把树边都标记. 然后对标记的边的两个端点, 我们add(u, v), ...

  4. cf 609E.Minimum spanning tree for each edge

    最小生成树,lca(树链剖分(太难搞,不会写)) 问存在这条边的最小生成树,2种情况.1.这条边在原始最小生成树上.2.加上这条半形成一个环(加上),那么就找原来这条边2端点间的最大边就好(减去).( ...

  5. 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 ...

  6. 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 ...

  7. 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 ...

  8. 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 ...

  9. 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 ...

随机推荐

  1. html 5 drag and drop upload file

    compatible: chrome firefox ie 11 , not supported demo: http://demo.tutorialzine.com/2011/09/html5-fi ...

  2. 用火狐打开PDF文件

    可以直接使用官方的Adobe Reader插件来实现在火狐中浏览PDF文件的功能.在你浏览一个PDF文件的时候,火狐将会尝试下载安装这个插件. 如果这个插件出现问题,那么就无计可施啦. 检查火狐的设置 ...

  3. 关于Eigen库在Visual Studio2013中传参对齐报错问题

    Error as follow: 具体问题及解决办法描述如下: (引自http://www.fx114.net/qa-278-97757.aspx) /************************ ...

  4. 第二天就跳票 将wikipedia上的英文词条翻译为中文 手动

    忙着改简历一整天,刚说完一天一博,就要跳票了. 还是写点东西吧. 今天又翻译了一个维基百科上的条目,刚过一天就忘了怎么弄,还得回头翻帖子.在这先记一下,省的以后找不到. 1.注册个wiki账号,轻松过 ...

  5. HDU1431+简单题

    题意简单 预处理之后会发现符合条件的数最多781个... 所以打表.. /* */ #include<algorithm> #include<iostream> #includ ...

  6. codeforces #310 div1 D

    一开始写了个暴力模拟绳子的摆动轨迹 然后在Test 16 T掉了 后来%了一下别人的代码,发现需要对特殊情况进行特殊处理 首先我们考虑绳子的向右摆动,设当前位置为p,绳子当前长度为L 如果其旋转中心位 ...

  7. photoshop:制作木板木纹

    1.设置颜色为木头相近颜色 2.滤镜->渲染->云彩 3.滤镜->杂色->添加杂色 4.滤镜->模糊->动感模糊 5.用矩形选取选取某块区域 6.滤镜->扭曲 ...

  8. SQL Server 2012 连接到数据库引擎

    第 1 课:连接到数据库引擎 https://msdn.microsoft.com/zh-cn/library/ms345332(v=sql.110).aspx   本课将介绍主要的工具以及如何连接并 ...

  9. P107、面试题15:链表中倒数第K个结点

    题目:输入一个链表,输出该链表中倒数第K个结点.为了符合大多数人的习惯,本体从1开始奇数,即链表的尾结点是倒数第1个结点.例如一个链表有6个结点,从头结点开始他们的值一次是1.2.3.4.5.6.这个 ...

  10. Windows平台下的session0创建进程的问题与解决办法

    很多博客都有记载如何在session0下创建进程的办法,也就是使用CreateProcessAsUser.但是这个要求服务的进程有SE_INCREASE_QUOTA_NAME和SE_ASSIGNPRI ...