bzoj 1123 [POI2008]BLO——点双连通分量
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1123
点双连通分量缩点,然后各种各样。
结果不会写了。比如新连边、记录一个点是割点缩成的点还是一块缩成的点什么的。
然后去学习了TJ。其实根本不用把缩点后的图真的建出来嘛!而且人家写得好好!唉,代码能力?
#include<iostream> #include<cstdio> #include<cstring> #define ll long long using namespace std; const int N=1e5+5,M=5e5+5; int n,m,hd[N],xnt,siz[N],dfn[N],low[N],tim; ll ans[N]; struct Ed{ int nxt,to;Ed(int n=0,int t=0):nxt(n),to(t) {} }ed[M<<1]; void add(int x,int y) { ed[++xnt]=Ed(hd[x],y);hd[x]=xnt; ed[++xnt]=Ed(hd[y],x);hd[y]=xnt; } void tarjan(int cr) { dfn[cr]=low[cr]=++tim;siz[cr]=1; ll t=0; for(int i=hd[cr],v;i;i=ed[i].nxt) if(!dfn[v=ed[i].to]) { tarjan(v); low[cr]=min(low[cr],low[v]);siz[cr]+=siz[v]; if(low[v]>=dfn[cr]) { ans[cr]+=t*siz[v];t+=siz[v]; } } else low[cr]=min(low[cr],dfn[v]); ans[cr]+=t*(n-t-1); } int main() { scanf("%d%d",&n,&m);int x,y; for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y);add(x,y); } tarjan(1); for(int i=1;i<=n;i++) printf("%lld\n",(ans[i]+n-1)<<1); return 0; }