您的位置:首页 > 其它

强联通分量 Tarjan算法

2015-01-21 19:31 323 查看
//上交红书模板
// 图有节点0~n-1,共n个节点
vector< pair<int, int> > g; //存有向边
vector<int> ans;  //染色结果

struct strongly_connected_components{
vector<int> &color;
vector<int> Stack;
int colorCnt, curr, *instack, *dfn, *low, *info, *next, *to;

void dfs ( int x ) {
dfn[x] = low[x] = ++ curr;
Stack.push_back( x );
instack[x] = true;
for ( int j = info[x]; j; j = next[j] ){
if ( ! instack[to[j]] ){
dfs ( to[j] );
low[x] = min ( low[x], low[to[j]] );
}
else{
if ( instack[to[j]] == 1 ){
low[x] = min ( low[x], dfn[to[j]] );
}
}
}
if ( low[x] == dfn[x] ){
while ( Stack.back() != x ){
color[Stack.back()] = colorCnt;
instack[Stack.back()] = 2;
Stack.pop_back();
}
color[Stack.back()] = colorCnt++;
instack[Stack.back()] = 2;
Stack.pop_back();
}
}

strongly_connected_components ( const vector< pair<int, int> > &edgeList,
int n, vector<int> &ans ) : color(ans) {
color.resize( n );
instack = new int
;
dfn = new int
;
low = new int
;
info = new int
;
next = new int[(int)edgeList.size() + 5];
to = new int[(int)edgeList.size() + 5];
fill_n( info, n, 0 );
for ( size_t i = 0; i < edgeList.size(); ++ i ){
to[i+1] = edgeList[i].second;
next[i+1] = info[edgeList[i].first];
info[edgeList[i].first] = i + 1;
}
fill_n( instack, n, 0 );
colorCnt = 0;
curr = 0;
for ( int i = 0; i < n; i ++ ){
if ( ! instack[i] ){
dfs ( i );
}
}
delete[] instack;
delete[] dfn;
delete[] low;
delete[] info;
delete[] next;
delete[] to;
}
};

int main()
{
int m, n;
while ( cin >> m >> n ){
int a, b;
g.clear();
ans.clear();
for ( int i = 0; i < n; i ++ ){
cin >> a >> b;
a --;
b --;
pair<int, int> tmp;
tmp.first = a;
tmp.second = b;
g.push_back ( tmp );
}
strongly_connected_components scc ( g, m, ans );
for ( int i = 0; i < ans.size(); i ++ ){
cout << ans[i] << ' ';
}
}
}

网上tarjan模板

HDOJ1269

图中任意两点强联通

#define MAX_V 11111

int V, E;
int dfn[MAX_V], low[MAX_V];
bool instack[MAX_V];
int din;
int cnt;
stack<int>s;
vector<int>Edge[MAX_V];

void tarjan(int x){
instack[x] = true;
dfn[x] = low[x] = din++;
s.push(x);
for (int i = 0; i < Edge[x].size(); i++){
int j = Edge[x][i];
if (!dfn[j]){
tarjan(j);
low[x] = min(low[x], low[j]);
}
else if (instack[j])
low[x] = min(low[x], dfn[j]);
}
if (dfn[x] == low[x]){
cnt++;
int tmp;
do{
tmp = s.top();
s.pop();
instack[tmp] = false;
}while (x != tmp);
}
}

int main(){
while (scanf("%d %d", &V, &E) && (V || E)){
for (int i = 0; i < V; i++)
Edge[i].clear();
for (int i = 0; i < E; i++){
int u, v;
scanf("%d %d", &u, &v);
Edge[u - 1].push_back(v - 1);
}
memset(dfn, 0, sizeof(dfn));
memset(instack, false, sizeof(instack));
din = 0;
cnt = 0;
for (int i = 0; i < V; i++){
if(!dfn[i])
tarjan(i);
}
if(cnt == 1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: