日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

图论 —— 图的连通性 —— Tarjan 缩点

發(fā)布時(shí)間:2025/3/17 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图论 —— 图的连通性 —— Tarjan 缩点 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

縮點(diǎn)常應(yīng)用于給一個(gè)有向圖,求在圖中最少要加多少條邊能使得該圖變成一個(gè)強(qiáng)連通圖

首先求出該圖的各個(gè)強(qiáng)連通分量,然后把每個(gè)強(qiáng)連通分量看出一個(gè)點(diǎn)(即縮點(diǎn)),最后得到了一個(gè)有向無(wú)環(huán)圖(DAG)

對(duì)于一個(gè)DAG,需要添加 max(a,b) 條邊才能使其強(qiáng)連通

其中 a 為 DAG 中出度為 0 的點(diǎn)總數(shù),b 為 DAG 中入度為 0 的點(diǎn)總數(shù)

int n,m; vector<int> G[N]; stack<int> S; int dfn[N],low[N]; bool vis[N];//標(biāo)記數(shù)組 int sccno[N];//記錄結(jié)點(diǎn)i屬于哪個(gè)強(qiáng)連通分量 bool in[N],out[N];//記錄入度、出度是否為0 int block_cnt;//時(shí)間戳 int sig;//記錄強(qiáng)連通分量個(gè)數(shù) void Tarjan(int x){vis[x]=true;dfn[x]=low[x]=++block_cnt;//每找到一個(gè)新點(diǎn),紀(jì)錄當(dāng)前節(jié)點(diǎn)的時(shí)間戳S.push(x);//當(dāng)前結(jié)點(diǎn)入棧for(int i=0;i<G[x].size();i++){//遍歷整個(gè)棧int y=G[x][i];//當(dāng)前結(jié)點(diǎn)的下一結(jié)點(diǎn)if(vis[y]==false){//若未被訪問(wèn)過(guò)Tarjan(y);low[x]=min(low[x],low[y]);}else if(!sccno[y])//若已被訪問(wèn)過(guò),且不屬于任何一個(gè)連通分量low[x]=min(low[x],dfn[y]);}if(dfn[x]==low[x]){//滿足強(qiáng)連通分量要求sig++;//記錄強(qiáng)連通分量個(gè)數(shù)while(true){//記錄元素屬于第幾個(gè)強(qiáng)連通分量int temp=S.top();S.pop();sccno[temp]=sig;if(temp==x)break;}} } void shrink(){//縮點(diǎn)memset(in,false,sizeof(in));memset(out,false,sizeof(out));for(int i=1;i<=sig;i++){//對(duì)于所有的強(qiáng)連通分量,將其入度、出度均視為1in[i]=true;out[i]=true;}for(int x=0;x<n;x++){//枚舉n個(gè)點(diǎn)for(int i=0;i<G[x].size();i++){//對(duì)第x個(gè)點(diǎn)的每個(gè)后繼節(jié)點(diǎn)int y=G[x][i];if(sccno[x]!=sccno[y]){//統(tǒng)計(jì)每個(gè)點(diǎn)出度、入度是否為0out[sccno[x]]=false;in[sccno[y]]=false;}}} } int main() {int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=0;i<n;i++)G[i].clear();while(m--){int x,y;scanf("%d%d",&x,&y);x--;y--;G[x].push_back(y);}sig=0;block_cnt=0;memset(vis,false,sizeof(vis));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(sccno,0,sizeof(sccno));//Tarjan求強(qiáng)連通分量for(int i=0;i<n;i++)if(vis[i]==false)Tarjan(i);shrink();//縮點(diǎn)int a=0,b=0;for(int i=1;i<=sig;i++){//統(tǒng)計(jì)入度、出度為0的點(diǎn)的個(gè)數(shù)if(in[i])a++;if(out[i])b++;}int res=max(a,b);if(sig==1)//強(qiáng)連通分量為1時(shí)res=0;printf("%d\n",res);} }

總結(jié)

以上是生活随笔為你收集整理的图论 —— 图的连通性 —— Tarjan 缩点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。