[POI 2008] BLO
阿新 • • 發佈:2018-07-31
tps inline ans bit c++ 搜索 class code sum
[題目鏈接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1123
[算法]
首先,如果一個點不是割點,那麽,去掉該點後不連通的有序點對就為 : 2 * (n - 1)
否則,去掉這個點後,這個圖就被分為了 :
1. 這個點本身
2. 這個點在搜索樹上的一些子樹
3. 除1,2這兩部分的節點
我們可以通過乘法原理算出答案,詳見代碼
[代碼]
#include<bits/stdc++.h> usingnamespace std; #define MAXN 100010 #define MAXM 500010 struct edge { int to,nxt; } e[MAXM << 1]; int i,n,m,x,y,timer,tot; int size[MAXN],dfn[MAXN],low[MAXN],head[MAXN]; long long ans[MAXN]; bool visited[MAXN],is_cut[MAXN]; inline void addedge(int u,int v) { tot++; e[tot] = (edge){v,head[u]}; head[u]= tot; } inline void tarjan(int u) { int i,v,cnt,sum; size[u] = 1; dfn[u] = low[u] = ++timer; visited[u] = true; cnt = sum = 0; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; if (!visited[v]) { tarjan(v); size[u]+= size[v]; low[u] = min(low[u],low[v]); if (dfn[u] <= low[v]) { sum += size[v]; cnt++; ans[u] += 1ll * size[v] * (n - size[v]); low[u] = min(low[u],low[v]); if (u != 1 || cnt > 1) is_cut[u] = true; } } else low[u] = min(low[u],dfn[v]); } if (!is_cut[u]) ans[u] = 2 * (n - 1); else ans[u] += 1ll * (n - 1) + 1ll * (n - sum - 1) * (sum + 1); } int main() { scanf("%d%d",&n,&m); for (i = 1; i <= m; i++) { scanf("%d%d",&x,&y); addedge(x,y); addedge(y,x); } tarjan(1); for (i = 1; i <= n; i++) printf("%lld\n",ans[i]); return 0; }
[POI 2008] BLO