CF 160D Edges in MST 最小生成树的性质,寻桥,缩点,批量处理 难度:3
2015-03-11 00:50
281 查看
http://codeforces.com/problemset/problem/160/D
这道题要求哪条边存在于某个最小生成树中,哪条边不存在于最小生成树中,哪条边绝对存在于最小生成树中
明显桥边一定存在于所有最小生成树中,然而怎么处理存在某个最小生成树的边呢?
借助kruskal算法的性质,由小到大,每次处理同一权值的边,如果边连接的点已经联通就不要管,否则那些处理的边一定存在于某最小生成树上
批量处理的思想很巧妙
这道题要求哪条边存在于某个最小生成树中,哪条边不存在于最小生成树中,哪条边绝对存在于最小生成树中
明显桥边一定存在于所有最小生成树中,然而怎么处理存在某个最小生成树的边呢?
借助kruskal算法的性质,由小到大,每次处理同一权值的边,如果边连接的点已经联通就不要管,否则那些处理的边一定存在于某最小生成树上
批量处理的思想很巧妙
#include <cstdio> #include <vector> #include <stack> #include <algorithm> using namespace std; const int maxn=2e5+5; int first[maxn]; struct edge{ int t,ind,nxt; }e[maxn]; int from[maxn],to[maxn],cost[maxn],index[maxn]; int sta[maxn]; int n,m,len; void addedge(int f,int t,int ind,int i){ e[i].nxt=first[f]; first[f]=i; e[i].t=t; e[i].ind=ind; } int par[maxn],num[maxn]; int fnd(int x){return par[x]==x?x:par[x]=fnd(par[x]);} void unit(int a,int b){ if(fnd(a)==fnd(b))return; num[fnd(b)]+=num[fnd(a)]; num[fnd(a)]=0; par[fnd(a)]=fnd(b); } bool cmp(int a,int b) {return cost[a]<cost[b];} int dfn[maxn],low[maxn],cnt; void dfs(int s,int f){ dfn[s]=low[s]=++cnt; for(int p=first[s];p!=0;p=e[p].nxt){ int t=e[p].t; if(p==(((f-1)^1)+1))continue; if(dfn[t]==0){ dfs(t,p); if(low[t]>dfn[s]){ sta[e[p].ind]=2; } else{ low[s]=min(low[s],low[t]); } } else { low[s]=min(low[s],dfn[t]); } } } int st[maxn],tail; void kruskal2(){ sort(index,index+m,cmp); for(int i=0;i<m&&num[fnd(1)]<n;){ int j=i; while(cost[index[i]]==cost[index[j]]&&j<m){j++;} for(int k=i;k<j;k++){ int indk=index[k]; if(fnd(from[indk])!=fnd(to[indk])){ st[tail++]=indk; sta[indk]=1; } } for(int p=0;p<tail;p++){ int tp=st[p]; int f=fnd(from[tp]),t=fnd(to[tp]); addedge(f,t,tp,++len); addedge(t,f,tp,++len); } for(int p=0;p<tail;p++){ int tp=st[p]; int f=fnd(from[tp]),t=fnd(to[tp]); dfs(f,0); unit(f,t); } cnt=0; len=0; for(int p=0;p<tail;p++){ int tp=st[p]; int f=fnd(from[tp]),t=fnd(to[tp]); first[f]=first[t]=0; dfn[f]=dfn[t]=0; } i=j; tail=0; } } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){par[i]=i;num[i]=1;} for(int i=0;i<m;i++){ scanf("%d%d%d",from+i,to+i,cost+i); index[i]=i; } kruskal2(); for(int i=0;i<m;i++){ if(sta[i]==2)puts("any"); else if(sta[i]==1)puts("at least one"); else puts("none"); } return 0; }
相关文章推荐
- 最小生成树的一些性质和理解
- CF 609E 最小生成树变种
- SPOJ COMPANYS Two Famous Companies 最小生成树,二分,思路 难度:2
- cf Inverse the Problem (最小生成树+DFS)
- 最小生成树(MST)的性质及算法 [转】
- poj 1789 Truck History 最小生成树 prim 难度:0
- 最小生成树的一些性质和理解
- poj 3522 Slim Span (最小生成树 的 一个性质 kruskal 的 应用 )
- poj 1258 Agri-Net 最小生成树 prim算法+heap不完全优化 难度:0
- UVALive 5905 Pool Construction 最小割,s-t割性质 难度:3
- CF 436D 最小生成树
- 最小生成树概念及性质
- 树链剖分,最小生成树(Drivers Dissatisfaction,cf 733F)
- hdu 4081 Qin Shi Huang's National Road System 树的基本性质 or 次小生成树思想 难度:1
- LA 5717枚举+最小生成树回路性质
- HDU 4081 Qin Shi Huang's National Road System 最小/次小生成树的性质
- 关于最小生成树的一些性质
- 最小生成树若干性质以及在ACM中的应用
- 最小生成树之MST性质
- HDU 4081 Qin Shi Huang's National Road System 最小/次小生成树的性质