Codeforces 19E 树上差分
2018-07-08 22:55
330 查看
思路:
先随便建出来一棵搜索树(图可能不连通?)
每一条非树边(剩下的边)和树边都可以构成一个环。
我们只看一个非树边和某些树边构成的这些环。
分成三种情况:
1.没有奇环 所有边都可以删
2.有一个奇环 奇环上的边可以删
3.有一堆奇环,一堆偶环
边化到点上
如果是奇环 非树边为(x,y) 在树上x,y这两个地方+1 lca(x,y)-2
偶环相反
做一遍树上递推上去
最后如果答案和奇环边的数量相等 这个边可以删。
//By SiriusRen #include <bits/stdc++.h> using namespace std; const int N=20050; int n,m,xx,yy,v ,next ,first ,tot,num,T,stk ,a ,odd,R ,remm,lastT, rev ,fa ,vis ,size ,son ,dfn ,cnt,top ,deep ,ans,ra ; struct Node{int x,y,wei;}rec ; void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;} void dfs1(int x){ size[x]=1,vis[x]=1,rev[++T]=x,stk[T]=x; for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x]){ if(vis[v[i]]){rec[++num].x=x,rec[num].y=v[i],rec[num].wei=i/2+1;continue;} R[v[i]]=i/2+1,deep[v[i]]=deep[x]+1,fa[v[i]]=x; dfs1(v[i]),size[x]+=size[v[i]]; if(size[v[i]]>size[son[x]])son[x]=v[i]; } } void dfs2(int x,int tp){ vis[x]=1,dfn[x]=++cnt;top[x]=tp; if(son[x])dfs2(son[x],tp); for(int i=first[x];~i;i=next[i])if(v[i]!=fa[x]&&v[i]!=son[x]&&!vis[v[i]])dfs2(v[i],v[i]); } int lca(int x,int y){ int fx=top[x],fy=top[y]; while(fx!=fy){ if(deep[fx]<deep[fy])swap(fx,fy),swap(x,y); x=fa[fx],fx=top[x]; }if(deep[x]<deep[y])return x;return y; } int main(){ memset(first,-1,sizeof(first)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++)scanf("%d%d",&xx,&yy),add(xx,yy),add(yy,xx); for(int i=1;i<=n;i++)if(!vis[i]){ dfs1(i);for(int j=lastT;j<=T;j++)vis[rev[j]]=0;dfs2(i,i);lastT=T; }for(int i=1;i<=num;i++){ if((deep[rec[i].x]%2)==(deep[rec[i].y]%2)) a[rec[i].x]++,a[rec[i].y]++,a[lca(rec[i].x,rec[i].y)]-=2,odd++,remm=rec[i].wei; else a[rec[i].x]--,a[rec[i].y]--,a[lca(rec[i].x,rec[i].y)]+=2; }if(!odd){printf("%d\n",m);for(int i=1;i<=m;i++)printf("%d ",i);return 0;} for(int i=n;i;i--)a[fa[stk[i]]]+=a[stk[i]]; for(int i=1;i<=n;i++)if(a[i]==odd)ra[++ans]=R[i]; if(odd==2)ra[++ans]=remm; printf("%d\n",ans),sort(ra+1,ra+1+ans); for(int i=1;i<=ans;i++)printf("%d ",ra[i]); }
相关文章推荐
- Codeforces 740D Alyona and a tree 二分+树上差分
- Codeforces 739B(树上路径倍增及差分)
- Codeforces Round #439 (Div. 2) Problem E (Codeforces 869E) - 暴力 - 随机化 - 二维树状数组 - 差分
- 缩点+树上差分——Codeforces555E Case of Computer Network
- bzoj 4326 运输计划 (树链剖分 + 树上差分 + 二分)
- 树上差分
- suoj22 WRX知识树(非递归dfs+树上差分)
- 【NOIP2015】运输计划(树上差分,二分答案)
- Codeforces 919D 拓扑排序判环 + 树上 dfs + dp
- Codeforces 932D - Tree 【树上倍增】
- [Noip2016]天天爱跑步 LCA+树上差分
- 【NOIP2016】天天爱跑步之树上差分
- Codeforces 280C Game on Tree 概率dp 树上随机删子树 求删完次数的期望
- BZOJ 4390: [Usaco2015 dec]Max Flow 树链剖分/树上差分
- NOIP2015 运输计划 树上差分(路径覆盖)
- [洛谷P2664]树上游戏-虚树-树上差分
- 【NOIP2016提高组T2】天天爱跑步-倍增LCA+树上差分
- 【例题】【树上差分】NKOJ3605 Max Flow
- Codeforces 853B Round #433 Div2D& Div1B Jury Meeting:差分前缀和+模拟
- [BZOJ4326][NOIP2015]运输计划(二分+dfs序+树上差分)