锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 銆 榪欐槸SCC闂鐨勭涓涓畻娉曪紝鐢盩arjan浜?972騫存彁鍑恒傜畻娉曚粛鐒跺熷姪DFS錛屼絾瀹冨茍涓嶄緷闈犻亶鍘嗛『搴忔潵鎶婁笉鍚岀殑SCC鍒嗙鍒頒笉鍚岀殑DFS鏍戜腑錛岃屾槸璁╁涓猄CC騫跺瓨浜庡悓涓涓狣FS鏍戜腑錛岀敤鏌愮鎵嬫鎶婁粬浠垎寮銆傝冭檻涓涓己鍒嗛噺C錛岃鍏朵腑絎竴涓鍙戠幇鐨勭偣涓簒錛岀敱鐧借礬寰勫畾鐞嗭紝C涓叾浠栫偣閮芥槸x鐨勫悗浠c傛垜浠笇鏈涘湪x璁塊棶瀹屾垚鏃剁珛鍒昏緭鍑篊銆?娉ㄦ剰榪欓噷鏄竴涓弗鏍肩殑鏁板鎻忚堪)銆傝繖鏍鳳紝灝卞彲浠ュ湪鍚屼竴媯礑FS鏍戜腑鍖哄垎寮鎵鏈夌殑SCC浜嗐傚洜姝ら棶棰樼殑鍏抽敭鏄細濡備綍鍒ゆ柇涓涓偣鏄惁涓篠CC涓渶鍏堣鍙戠幇鐨勭偣銆?br>銆
Tarjan綆楁硶錛?/p>
銆 濡傚浘銆?img style="WIDTH: 384px; HEIGHT: 259px" border=0 alt=dfs鏍?align=right src="http://m.shnenglu.com/images/cppblog_com/mtysblog/Tarjan.jpg" width=384 height=259>鍋囪鎴戜滑姝e湪鍒ゆ柇u鏄惁涓烘煇SCC涓涓涓鍙戠幇鐨勮妭鐐廣傚鏋滄垜浠彂鐜頒粠u鐨勫効瀛愬嚭鍙戝彲浠ュ埌杈緐鐨勭鍏坵,鏄劇劧u\v\w鍦ㄥ悓涓涓猄CC涓紝鍥犳u涓嶆槸璇CC絎竴涓鍙戠幇鐨勮妭鐐廣傚鏋滀粠v鍑虹幇鏈澶氬彧鑳藉埌u錛岄偅涔坲鏄SCC涓涓涓鍙戠幇鐨勮妭鐐癸紙涔熻鏈夊悓瀛︿細闂紝鑻ユ墍鏈夊瓙鑺傜偣涓嶈兘鍒拌揪u鏈韓錛屼綍浠ヨ兘璇存槑u鏄拰瀛愭爲寮鴻仈閫氱殑錛熷叾瀹炵敱浜嶥FS鐨勭壒鐐癸紝鑻ヨ繖鏍風殑鎯呭喌鍑虹幇錛屽疄闄呬笂鍦╱鐨勫瓙鏍戜笂宸茬粡瀹屾垚浜嗕竴涓己鍒嗛噺鐨勫鎵撅紝u姝ゆ椂鏄彧鍒板畠鏈韓鐨?#8220;絎竴涓?#8221;琚彂鐜拌妭鐐癸紝鍘熶功鐨勬弿榪版槸涓ユ牸鍜屽綊綰崇殑錛夈傝繖鏍鳳紝闂杞寲涓烘眰錛氫竴涓偣u鏈榪滆兘鍒拌揪鐨勭鍏堢殑d鍊箋傛敞鎰忚繖閲岀殑“鍒拌揪”鍙互閫氳繃鍚庡悜杈規垨浜ゅ弶杈癸紝浣嗘槸鍓嶆彁鏄彧鑳介氳繃鏍堥噷闈㈢殑鐐硅屼笉鏄凡緇忕‘瀹歋CC緙栧彿鐨勫叾浠栫偣銆傚浘涓疄綰胯〃紺轟竴鏉¤竟錛岃櫄綰胯〃紺轟竴鏉℃垨澶氭潯杈廣?br>
瀹氫箟low[u]涓簎鍙婂叾鍚庝唬鑳借拷婧埌鐨勬渶鏃╃鍏坴鐨勫彂鐜版椂闂存埑pre[v]錛屾垜浠彲浠ュ湪璁$畻low鍑芥暟鐨勫悓鏃跺畬鎴怱CC鐨勮綆楋紝low鍑芥暟鐨勯掓帹鏂規硶濡備笅錛?br> 鍒╃敤鍏ㄥ眬鏍坃sta淇濆瓨褰撳墠SCC涓殑鑺傜偣錛堟敞鎰忔爤涓妭鐐瑰艦鎴愭爲鑰屼笉涓瀹氭槸閾撅級錛宑nt涓哄紑鍙戝綋鍓嶇偣u鐨勬椂闂存埑錛宻cnt涓哄己鍒嗛噺緙栧彿鍣紝id[]涓哄己鍒嗛噺緙栧彿鏁扮粍銆?br>
鍘熷鐨凾arjan綆楁硶閫掓帹鏂瑰紡涓猴細濡傛灉 pre[w]<pre[u]涓攚鍦ㄦ爤涓紝鍒檒ow[u]=min{pre[w],low[u]}錛屾敞鎰忓悗涓涓檺鍒舵槸涓轟簡淇濊瘉w涓嶆槸鍦ㄥ彟涓涓凡緇忓彂鐜扮殑SCC涓備笅闈㈢殑浠g爜鏇寸畝媧侊紝鍦ㄦ爣璁板己鍒嗛噺鍚庯紝鍙渶瑕佸皢low[w]璁句負鏈澶у鹼紝琛ㄦ槑瀹冧笉鍐嶆槸浠諱綍鐐圭殑紲栧厛錛岄偅涔坵灝變笉浼氳鍏朵粬寮哄垎閲忓惛鏀朵簡錛屾兂鎯充負浠涔堛?br>
void dfs-scc(int u)
{
2
int w,min;
3
min=low[u]=pre[u]=cnt++;
4
/**//* 鍒濆鍖栨椂闂存埑錛宭ow鍊鹼紝瀛愯妭鐐規渶灝忕鍏?nbsp;涓哄綋鍓嶆椂闂存埑 */
5
_sta.push(u);
6
7
for each (u,w)
{
8
if(pre[w]==-1) dfs-scc(w);
9
/**//* 鏈紑鍙戣妭鐐?nbsp;*/
10
if( low[w]<min ) min=low[w];
11
/**//* 姹傚嚭u鎵鏈夊効瀛恑鏈榪滆兘鍒拌揪鐨勭鍏?nbsp;*/
12
}
13
14
if(min<low[u])
{ low[u]=min; return ; }
15
/**//* 鎵鏈夌殑鍎垮瓙鑳藉埌杈劇殑鏈榪滅鍏堟槸u鐨勭鍏堬紝鍥犳u涓嶆槸SCC
16
絎竴涓鍙戠幇鐨勮妭鐐癸紝閫氳繃瀛愯妭鐐癸紝u搴旇兘鍒拌揪榪欐牱鐨勭涓涓妭鐐?nbsp;*/
17
do
{
18
w=_sta.pop(w);
19
id[w]=scant;
20
low[w]=0x7fffffff; /**//* 閿佸畾low錛屼繚璇亀涓嶄細琚叾浠栧己鍒嗛噺鍚告敹 */
21
}while(w!=u)
22
/**//* 姝ゆ椂錛寀鐨勬墍鏈夊瓙鑺傜偣蹇呰兘涓旀渶榪滀粎鑳藉埌杈緐錛屼粬浠矡閫氭瀯鎴愪竴涓猄CC */
23
scant++;
24
}
]]>
鍒╃敤騫垮害浼樺厛鎼滅儲鍙互鍒ゆ柇涓涓浘鏄惁涓轟簩鍒嗗浘銆傝搗鐐箂鏄劇劧鍙互闅忔剰瀹氳壊錛屾瘡嬈¤冭檻涓鏉¤竟(u,v)鏃舵樉鐒秛鎵鍦ㄩ泦鍚堝凡瀹氾紝鍥犳褰搗涓虹櫧鑹叉椂鎶婂畠鏀懼埌涓嶅寘鍚玼鐨勯偅涓泦鍚堬紝鑰屽綋v涓虹伆鑹叉垨榛戣壊鏃?姝ゆ椂v鎵鍦ㄩ泦鍚堝凡緇忕‘瀹?媯鏌鍜寀鏄惁鍦ㄥ悓涓涓泦鍚堛傚鏋滄槸錛屽垯璇ュ浘涓嶆槸浜屽垎鍥撅紝澶辮觸閫鍑恒傚鏋滄槸娌℃湁澶辮觸錛屽垯綆楁硶瀹為檯涓婂凡緇忔瀯閫犲嚭浜嗚繖涓や釜闆嗗悎銆傚湪蹇界暐s鎵鍦ㄩ泦鍚堢殑鎯呭喌涓嬶紝榪欎釜闆嗗悎鐨勫垎鍒掓槸鍞竴鐨勶紙綆楁硶姝ラ涓殑姣忎竴姝ラ兘鏄己鍒剁殑錛夈?/span>


bool Is_BipartiteGraph(int n,int id[] /**//* 浜屽垎鑺傜偣闆?nbsp;*/ )
{
int k,cnt=0;
enum
{Gray,Black,White} color[N];
queue<int> _que;
for(int i=0;i<n;i++) color[i]=White;
_que.push(0); color[0]=Black; id[0]=cnt;
while(!_que.empty())
{
k=_que.front(); _que.pop();
for(int i=0;i<n;i++)
if( g[k][i] )
{
if( Gray == color[i] | Black == color[i] )
{
if( id[i] == id[k] ) return false;
}
else
{
id[i]=1-id[k];
color[i]=Gray;
_que.push(i);
}
}
color[k]=Black;
}
return true;
}
enum
{ Tree,Back,Forward,Cross } id[N][N];
enum
{ Black,White,Gray } color[N]=
{White};
int finish[N],find[N];
int time=0;
void DFS(int s)
{
color[s]=Gray; // 寮濮嬫墿灞?nbsp;
find[s]=++time;
for(int i=0;i<n;i++)
if(g[s][i])
{
switch (color[i])
{
case White:
{
id[s][i]=Tree;
DFS(i);
break;
}
case Gray:
{
id[s][i]=Back;
break;
}
case Black:
{
if(find[s]<find[i]) id[s][i]=Forward;
else id[s][i]=Cross;
break;
}
}
}
color[s]=Black; //浜嬩歡緇撴潫
finish[s]=++time;
}