loj10099 點雙連通分量

2021-08-28 12:47:21 字數 2462 閱讀 8041

點雙連通分量+判斷割點。(99是乙個神奇的題號值得紀念!!)

void tarjan(int k,int pre)

++sz[scc]; dt[scc].push_back(k);

}//k是某個點雙的割點,可以統計那整個點雙了。

low[k]=min(low[k],low[v]);

}else low[k]=min(low[k],dfn[v]);

}}

然而並不是乙個模版了事的啊qaq。

這道題的解法詭異……幾乎和yy沒什麼區別了,然而菜雞的我不能理解,於是試圖證明。

->yy了很久以後,發現我不會證。

然後我想到了某個黑科技。關於點雙,有種神奇的東西叫圓方樹。

->以下是鬼畜的yy式證明。

建一棵圓方樹,把除了割點以外的圓點都刪掉,那麼它就沒有圓葉子了,而原本所有的割點都是父親,它仍然是乙個完整的樹。

對於不只乙個方點的樹:

1.對於只和乙個割點相鄰的點雙,顯然地能且只能在內部放乙個。->圓方樹的每個方葉子一定放了。

證明:必要性:考慮割點坍塌的情況,此時不能走到別的點雙,所以是必要的。

充分性:在所有方葉子都放了的情況下,(割點坍塌的情況處理好了),考慮內部點坍塌的情況。由於點雙的性質,還是可以通過割點走到其他方葉子的。

2.對於和多個割點相鄰的點雙,在圓方樹上對它進行觀察,一旦乙個割點塌了,它一定還是可以走到某個方葉子的。->多個割點的點雙不用放。

對於只有乙個方點的樹:

對於單獨的方點,它只能在內部任意選兩個點放,不然放的點塌了它就gg了。

證(y)明(y)完了。

#includeusing namespace std;

#define rep(x,y,z) for (int x=y; x<=z; x++)

#define downrep(x,y,z) for (int x=y; x>=z; x--)

#define ms(x,y,z) memset(x,y,sizeof(z))

#define ll long long

#define repedge(x,y) for (int x=hed[y]; ~x; x=edge[x].nex)

inline int read()

const int n=1005;

const int m=505;

int n,m,nedge,hed[n],dfn[n],low[n],tot,root,cut[n],scc,bel[n],sum[n],cas;

ll sz[n];

stacks;

vectordt[n];

struct edgeedge[m<<1];

void addedge(int a,int b)

void tarjan(int k,int pre)

++sz[scc]; dt[scc].push_back(k);

}low[k]=min(low[k],low[v]);

}else low[k]=min(low[k],dfn[v]); }}

int main()

rep(i,1,scc) dt[i].clear(); ms(sz,0,sz); ms(cut,0,cut);

scc=0; ms(dfn,0,dfn); rep(i,1,n) if (!dfn[i])

//rep(i,1,scc)

const int n=205;

const int m=n*n;

const int inf=305;

int n,m,s,t,scc,nedge,tot,cut[n],hed[n],dfn[n],low[n],head[n],nedge,f[n],root;

struct edgeedge[m<<1],e[m<<1];

stacks;

void adde(int a,int b)

void addedge(int a,int b)

void tarjan(int k,int pre)

adde(k,n+scc); adde(n+scc,k);

} low[k]=min(low[k],low[v]);

}else low[k]=min(low[k],dfn[v]); }}

#define repe(x,y) for(int x=head[y]; ~x; x=e[x].nex)

int dfs(int k,int fa)

} return res;

}int main()

s=read(); t=read(); nedge=0; ms(head,-1,head);

rep(i,1,n) if (!dfn[i])

int ans=dfs(s,s); if ((!ans)||(f[s]>=inf)) puts("no solution"); else printf("%d\n",f[s]);

return 0;

}

雙連通分量

在無向連通圖中,如果刪除該圖的任何乙個結點都不能改變該圖的連通性,則稱該圖是雙連通的。雙連通無向圖一定是連通的,而連通的無向圖則不一定是雙連通的。對於乙個連通的無向圖也有雙連通分量的概念,定義自然不言而喻。同樣,我們也可以利用tarjan演算法求雙連通分量。define n 10000 struct...

雙連通分量

在乙個無向連通圖中,如果任意去掉乙個定點i及依附於i的所有邊後得到的圖仍然連通,則稱該圖為 2 連通圖 否則,若得到多個連通分量,則該圖不是雙連通的,頂點i被稱為 割點 簡單的說,在雙連通圖中,任何一對頂點都至少存在兩條路徑可以互相到達。圖的連通 性不會任何乙個頂點的影響。這個性質具有許多重要的應用...

雙連通分量

雙連通分量就是無向圖中的強連通分量,基本就是找割頂和橋。割頂就是乙個點,如果把它取掉,連通分量數量就會增加,橋就是一條邊,同理。對於乙個連通圖,如果任意兩點至少存在兩條 點不重複 的路徑,也就是任意兩條邊都在乙個簡單環中,即內部無割頂,則說這個圖是點雙連通的。對於乙個連通圖,如果任意兩點至少存在兩條...