就是生成搜尋樹,然後找返祖邊。
模板:
vector ljb[n];
int dfn[n],low[n],tim,num,belong[n];
bool ex[n];
stack st;
void tarjan(int x)
;gg a;
vector ljb1[a];
int dfn[a],low[a],tim,num,belong[a];
bool ex[a];
stack st;
void tarjan(int fa,int x)
for(int y=0;y(情報傳遞)
時間限制: 2000 ms 記憶體限制: 262144 kb
【題目描述】
有乙個情報網共有n個人,通過有向的**線聯絡。為保證通訊安全,需要滿足一些要求,這些要求分為兩類:
①從第a個人通過一條或多條**線可以聯絡到第b個人;
②從第a個人通過一條或多條**線不能聯絡到第b個人。
現在作為總工程師的你需要構造乙個合法的情報網,使得這個情報網滿足給定要求,或者告訴情報機構這樣的情報網是不存在的。
【輸入】
第一行乙個整數n表示人數。
第二行乙個整數m表示第一類要求的個數,接下來m行每行兩個整數a,b表示要求。
第m+3行乙個整數t表示第二類要求的個數,接下來t行每行兩個整數a,b表示要求。
【輸出】
若不存在這樣的情報網,輸出一行「no」(不含引號)。
否則在第一行輸出「yes」(不含引號),在第二行輸出情報網中**線的數量p,接下來p行每行兩個整數u,v,描述一條u→v的**線。由於資源有限,要求p≤n+m+t。
【輸入樣例】32
1 22 3
11 3
【輸出樣例】
no【提示】
【輸入樣例2】32
1 22 3
13 1
【輸出樣例2】
yes2
1 22 3
【資料規模】
對於20%的資料,n
≤1000
n≤1000
n≤1000
;對於60%的資料,n
≤25000
n≤25000
n≤2500
0;對於100%的資料,1≤n
,m,t
≤105,1
≤a,b
≤n,a
≠b
1≤n,m,t≤105,1≤a,b≤n,a≠b
1≤n,m,
t≤10
5,1≤
a,b≤
n,a
=b。
思路:第一類要求必連,連好縮點後重新構圖,深搜判斷第二類要求。
注意:判斷時一組資料搜一次要tle,可以按染色排序(將乙個強聯通分量中的點放一起判斷),每個強聯通分量深搜一次即可。
程式:#include#define ll long long
using namespace std;
const ll a=1e5+5;
ll n;
ll m,a[a],b[a];
vector ljb[a];
ll t;
struct gg
;gg no[a];
ll dfn[a],low[a],tim,be[a],num;
bool ex[a];
stack st;
void tarjan(ll x)
}int main()
for(ll i=1;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(ll i=1;i<=n;i++)
for(ll y=0;yscanf("%lld",&t);
for(ll i=1;i<=t;i++)
scanf("%lld%lld",&no[i].a,&no[i].b);
sort(no+1,no+1+t,comp);
for(ll i=1;i<=t;i++)
if(go[be[no[i].b]]==1)
}printf("yes\n%lld\n",m);
for(int i=1;i<=m;i++)
printf("%lld %lld\n",a[i],b[i]);
return 0;
}
強連通分量 tarjan求強連通分量
雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...
強連通分量
對於有向圖的乙個頂點集,如果從這個頂點集的任何一點出發都可以到達該頂點集的其餘各個頂點,那麼該頂點集稱為該有向圖的乙個強連通分量。有向連通圖的全部頂點組成乙個強連通分量。我們可以利用tarjan演算法求強連通分量。define n 1000 struct edge e 100000 int ec,p...
強連通分量
在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected components 下圖中,子圖為乙個強連通分量,因為...