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

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

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

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. 使用MyBatis的resultMap高级查询时常用的方式总结

    以下内容已经通过楼主测试, 从pd设计数据库到测试完成, 之前楼主也没有过Mybatis 使用resultMap觉得有点乱,最近抽出时间总结了一下也算对MyBatis的resultMap进行一次系统的 ...

  2. 前端跨域之html5 XMLHttpRequest Level2

    前端代码 var xhr=new XMLHttpRequest(); xhr.open('POST','http://127.0.0.1:8081/ceshi',true); xhr.onreadys ...

  3. sql之解决数据库表的循环依赖问题

    三张数据表关系如图: 其实出现表循环依赖情况:就是 同时  ConfigCompany和 Department 也有依赖,就会报错,说有循环依赖,就会报错. 所以 这个时候的解决办法:可以改 在数据库 ...

  4. 各个浏览器下实现Ajax的JS

    var xmlhttpget; try {     // Firefox, Opera 8.0+, Safari     xmlhttpget = new window.XMLHttpRequest( ...

  5. 1187: [HNOI2007]神奇游乐园 - BZOJ

    Description 经历了一段艰辛的旅程后,主人公小P乘坐飞艇返回.在返回的途中,小P发现在漫无边际的沙漠中,有一块狭长的绿地特别显眼.往下仔细一看,才发现这是一个游乐场,专为旅途中疲惫的人设计. ...

  6. 1026: [SCOI2009]windy数 - BZOJ

    Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数?Inp ...

  7. [转载]Sublime Text 2 - 性感无比的代码编辑器!程序员必备神器!跨平台支持Win/Mac/Linux

    代码编辑器或者文本编辑器,对于程序员来说,就像剑与战士一样,谁都想拥有一把可以随心驾驭且锋利无比的宝剑,而每一位程序员,同样会去追求最适合自己的强大.灵活的编辑器,相信你和我一样,都不会例外. 我用过 ...

  8. LA 4731

    dp[i][j]意思是前i个分成j组最小的花费 #include<cstdio> #include<algorithm> #include<cstring> #in ...

  9. Error building Player: CommandInvokationFailure: Failed to re-package resources. See the Console for details. ShareSDK 也有这种错误

    Error building Player: CommandInvokationFailure: Failed to re-package resources. See the Console for ...

  10. 91. Decode Ways

    题目: A message containing letters from A-Z is being encoded to numbers using the following mapping: ' ...