LouZhang

导航

poj_2762,弱连通

http://poj.org/problem?id=2762

这题是求弱连通

弱连通就是无向图强连通(基图是有向图)

思路:先targan缩点,然后这些点求最长链

也就是这些点(缩点)在一棵树上,这棵树的深度应该为强连通分量个数。。

画个图就好理解了

#include<cstdio>
#include<cstring>

const int maxn(1111);
struct Edge{
    int v, next;
}e1[maxn*6], e2[maxn*6];
int head1[maxn], cnt1, head2[maxn], cnt2;
int low[maxn], dfn[maxn], vis[maxn], belong[maxn];
int stack[maxn], step, color, top;
void init(){
    memset(head1, -1, sizeof head1);
    cnt1 = cnt2 = 0;
    memset(head2, -1, sizeof head2);
    memset(vis, 0, sizeof vis);
    memset(dfn, 0, sizeof dfn);
    memset(belong, -1, sizeof belong);
    step = color = top = 0;
}
void add_Edge(int u, int v){
    e1[cnt1].v = v, e1[cnt1].next = head1[u];
    head1[u] = cnt1 ++;
}
int n, m;
int f[maxn][maxn], ind[maxn];

void targan(int u){
    dfn[u] = low[u] = ++ step;
    stack[top++] = u;
    vis[u] = 1;
    for(int i = head1[u]; i != -1; i = e1[i].next){
        int v = e1[i].v;
        if(!dfn[v]){
            targan(v);
            if(low[u] > low[v])
              low[u] = low[v];
        }
        else
          if(vis[v] && low[u] > dfn[v])
            low[u] = dfn[v];
    }
    if(dfn[u] == low[u]){
        color ++;
        int s;
        do{
            s = stack[--top];
            vis[s] = 0;
            belong[s] = color;
        }while(s != u);
    }
}
void add_edge(int u, int v){
    e2[cnt2].v = v, e2[cnt2].next = head2[u];
    head2[u] = cnt2 ++;
}
int dp[maxn];
int cnt;
void dfs(int u){
    for(int i = head2[u]; i + 1; i = e2[i].next){
        int v = e2[i].v;
        if(dp[v] < dp[u] + 1)
            dp[v] = dp[u] + 1;
        if(dp[v] > cnt) cnt = dp[v];
        dfs(v);
    }
}
int check(){
    cnt = 0;
    int u;
    for(int i = 1; i <= color; i ++){
        if(ind[i] == 0){
            cnt ++;
            if(cnt > 1) return 0;
            u = i;
        }
    }
    /*
    cnt = 1;
    printf("%d\n", e2[u].next);
    while(e2[u].next != -1){
        cnt ++;
        u = e2[u].v;
        puts("|asdf");
    }*/
    memset(dp, 0, sizeof dp);
    cnt = 0;
    dfs(u);
    if(cnt == color - 1) return 1;
    return 0;
}
void solve(){
    for(int i = 1; i <= n; i ++)
      if(!dfn[i])
        targan(i);
    if(color == 1){
        puts("Yes");
        return;
    }
    memset(ind, 0, sizeof ind);
    memset(f, 0, sizeof f);
    for(int i = 1; i <= n; i ++){
        for(int j = head1[i]; j + 1; j = e1[j].next){
            int v = e1[j].v;
            int u = belong[i];
            v = belong[v];
            if(u != v && !f[u][v]){
                add_edge(u, v);
                ind[v] ++;
                f[u][v] = 1;
            }
        }
    }
    if(check())
      puts("Yes");
    else
      puts("No");
}
int main(){
    int tcase;
    scanf("%d", &tcase);
    while(tcase --){
        init();
        scanf("%d%d", &n, &m);
        while(m --){
            int u, v;
            scanf("%d%d", &u, &v);
            add_Edge(u, v);
        }
        solve();
    }
    return 0;
}
/*
1
7 8
1 2
3 1
3 2
2 4
4 7
4 5
5 6
6 4
YES
*/

posted on 2012-09-06 12:13  louzhang_swk  阅读(228)  评论(0编辑  收藏  举报