1. 程式人生 > >LOJ-10104(割點+dfs)

LOJ-10104(割點+dfs)

結果 傳送門 print init sizeof clas oid lld play

題目鏈接:傳送門

思路:

求割點的同時求割點刪除後所剩的不連通的點的對數,在遍歷完成後回溯統計點的個數,具體操作見代碼;

註意:結果是long long 類型。

技術分享圖片
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
int head[maxn],next[maxn],ver[maxn],tim;
LL size[maxn],ans[maxn];
int low[maxn],num[maxn],tot,m,n;
int MIN(int x,int y) { return x<y?x:y; } void Init() { memset(head,0,sizeof(head)); memset(num,0,sizeof(num)); memset(low,0,sizeof(low)); memset(ans,0,sizeof(ans)); memset(size,0,sizeof(size)); tot=0;tim=0; } void addedge(int u,int v) { ver[++tot]=v;next[tot]=head[u];head[u]=tot; }
void Tarjan(int u) { low[u]=num[u]=++tim; size[u]=1; int i,v,cnt=0; LL tp=0; for(i=head[u];i;i=next[i]){ v=ver[i]; if(!num[v]){ cnt++; Tarjan(v); size[u]+=size[v]; //統計每一個相鄰節點 low[u]=MIN(low[u],low[v]); if(num[u]<=low[v]){ ans[u]
+=(LL)tp*size[v]; //已知區塊節點數*相鄰區塊的節點數 tp+=size[v];//更新已知區塊 } } else low[u]=MIN(low[u],num[v]); } ans[u]+=tp*(n-1-tp);//因為是連通圖,所以要增加除了相鄰節點以外圖中剩余未訪問的節點的數量和 } int main(void) { int i,j,x,y; while(~scanf("%d%d",&n,&m)){ Init(); 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]+n-1)*2); } return 0; }
View Code

LOJ-10104(割點+dfs)