Codeforces160D Edges in MST
来源:互联网 发布:图书管理系统java项目 编辑:程序博客网 时间:2024/05/17 02:02
传送门
题目大意
给定一幅
边权范围
题解
一个最初的想法就是先随便跑出一棵MST,然后考虑每条非树边对应的路径上是否有与其权值相等的边可以替换.
容易知道其实与考虑的非树边权值相等的边只可能为路径上权值最大的边.
然而这样的边可能有多条,树剖+线段树维护会比较麻烦,并没有去敲.
这样可以做到时间复杂度
然而还有一种更机智的做法,不过可能这里不好讲清楚,可以去看官方题解.
在进行Kruskal算法时,我们把所有权值相等的边同时考虑.其中如果有某条边的两个顶点已经属于一个连通块,那么这条边肯定不会加入MST中.
对于其他的边,它们单独的作用就是把两个连通块合并.不管这些边中具体哪些加入了MST中,它们最终的作用一定是把这些连通块全都合并起来了.如果一条边必须出现在MST中,那么就是说如果不加入这条边就不能把其中的两个连通块合并了.
是不是和图的连通性中的桥的概念很像?
所以方法就是把加入这些边之前的那些连通块看作点构建新图,dfs搜一遍求出桥后那些桥就是必须出现在MST中的边,否则就是无法确定.然后再把这些连通块合并.
这样做的时间复杂度除去给边排序和并查集之外是
具体实现可以看代码.
代码
#include<cstdio>#include<algorithm>using namespace std;const int N=1e5+5;int tot_edge,head[N],dfs_clock,pre[N],par[N],ans[N];// ans[i]=0:any 1:at least one 2:nonevoid rd(int &res){ res=0; char c; while(c=getchar(),c<48); do res=(res<<3)+(res<<1)+(c^48); while(c=getchar(),c>47);}struct EDGE{ int u,v,cost,id; inline void Rd(){ rd(u);rd(v);rd(cost); } inline bool operator <(const EDGE &tmp)const{ return cost<tmp.cost; }}es[N];struct Edge{ int to,nxt,id;}edge[N<<1];void add_edge(int u,int v,int id){ edge[tot_edge]=(Edge){v,head[u],id}; head[u]=tot_edge++;}int get_root(int x){ return par[x]==x?x:par[x]=get_root(par[x]);}inline void Min(int &a,int b){ if(b<a)a=b;}int dfs(int u,int id){ int lowu=pre[u]=++dfs_clock; for(int i=head[u];~i;i=edge[i].nxt){ int v=edge[i].to; if(!pre[v]){ int lowv=dfs(v,i); Min(lowu,lowv); if(lowv>pre[u])ans[edge[i].id]=0; } else if(pre[v]<pre[u]&&i!=(id^1)){ Min(lowu,pre[v]); } } return lowu;}void unite(int u,int v){ u=get_root(u); v=get_root(v); if(u==v)return; par[u]=v;}int main(){ int n,m; rd(n);rd(m); for(int i=1;i<=n;++i) par[i]=i; for(int i=0;i<m;++i){ es[i].Rd(); es[i].id=i; } sort(es,es+m); for(int i=0;i<m;){ int j=i; while(j+1<m&&es[j+1].cost==es[j].cost)++j; tot_edge=dfs_clock=0; for(int k=i;k<=j;++k){ es[k].u=get_root(es[k].u); es[k].v=get_root(es[k].v); int u=es[k].u,v=es[k].v; head[u]=head[v]=-1; pre[u]=pre[v]=0; } for(int k=i;k<=j;++k){ int u=es[k].u,v=es[k].v,id=es[k].id; if(u==v){ ans[id]=2; continue; } ans[id]=1; add_edge(u,v,id); add_edge(v,u,id); } for(int k=i;k<=j;++k){ if(!pre[es[k].u])dfs(es[k].u,-1); } for(;i<=j;++i) unite(es[i].u,es[i].v); } for(int i=0;i<m;++i){ if(ans[i]==2)puts("none"); else puts(ans[i]?"at least one":"any"); } return 0;}/* Jun.24.16 Tags:tree,MST,dsu,dfs,bridge Submissions:2 Time 122ms Memory 8100KB*/
0 0
- Codeforces160D Edges in MST
- Codeforces 160D Edges in MST
- [Codeforces]160D - Edges in MST
- codeforces 160D Edges in MST
- codeforces 160D - Edges in MST
- CodeForces 160D Edges in MST 题解
- CF 160D Edges in MST
- CodeForces 160D Edges in MST (tarjan)
- CodeForces 160D - Edges in MST kruskal+tarjan求无向图的桥
- Codeforces 160D Edges in MST【思维+并查集+求桥(有重边)】
- UVA 11747 - Heavy Cycle Edges(MST)
- UVA 11747 Heavy Cycle Edges(MST)
- Operations on edges in polyhedron
- working experience in MST
- detects edges in an image using the homogeneity operator
- Submodularity beyond submodular energies: Coupling edges in graph cuts
- poj -- 2075 Tangled in Cables (mst)
- uva10816 Travel in Desert(MST + 最短路)
- TableViewCell注册及复用
- 【数字图像处理学习笔记之三】Blob分析
- Android弹出软键盘时如何将底部顶上去
- Scramble String
- SpringMVC入门
- Codeforces160D Edges in MST
- Serializable deep copy
- Poj 2723 Go Deeper【2-SAT-----Tarjan强连通+二分】
- 使用颜色当图片
- kinect动作捕捉
- 基于内存数据网格的REST数据服务
- 第18章类加载机制和反射
- su和su - 区别
- 添物零基础到大型全栈架构师 不花钱学计算机及编程(预备篇)— 数据库