poj 2762 Going from u to v or from v to u

来源:互联网 发布:android之淘宝购物车 编辑:程序博客网 时间:2024/05/17 01:14

类型:有向图连通性

题目:http://poj.org/problem?id=2762 判断一个有向图单向连通性

来源:POJ Monthly--2006.02.26,zgl & twb

思路:对于强连通分量中的点相互连通,可以将其看做一个点处理。搜索所有的强连通分量,对强连通分量缩点后,构造新图进行拓扑排序,判断是否成链。如果成链,结果为真。假如不成链,即存在某时刻两个点的入度都为0,则该两点不连通。

// poj 2762 - Going from u to v or from v to u// ac 1308K344MS#include <iostream>#include <iomanip>#include <fstream>#include <sstream>#include <algorithm>#include <queue>#include <stack>#include <map>#include <string>#include <cmath>#include <cstring>#include <cstdlib>using namespace std;#define MIN(a,b) (a < b ? a : b)#define clr(a,b) memset(a,b,sizeof(a))#define FOR(i,a,b) for((i) = (a); (i) < (b); ++i)#define FORE(i,a,b) for((i) = (a); (i) <= (b); ++i)#define MAXN 1010#define MAXM 6010bool in_stack[MAXN],graph[MAXN][MAXN];int num,cnt,count_node,kk,m,n,cnt_num;int in[MAXN];int step[MAXN];int low[MAXN];int head[MAXN];int belong[MAXN];stack<int> st;struct edge{    int v,nxt;}e[MAXM];void Tarjan(int u) {    int v;    int i,j;    step[u] = low[u] = ++num;    st.push(u);    in_stack[u] = true;    for(i = head[u]; i != -1; i = e[i].nxt){        v = e[i].v;        if(!step[v]){            Tarjan(v);            low[u] = MIN(low[u],low[v]);        }        else if(in_stack[v])            low[u] = MIN(low[u],step[v]);    }    if(step[u] == low[u]){        cnt_num++;        do{            j = st.top();            st.pop();            in_stack[j] = false;            belong[j] = cnt_num;        }while(j != u);    }}bool topo() {    int i,j;    int tmp,k,in_num;    tmp = 0;    while(1){        k = in_num = 0;        FORE(i,1,cnt_num)            if(in[i] == 0){                in_num++;                k = i;            }        if(in_num > 1)            return 0;        if(k == 0)            break;        FORE(j,1,cnt_num)            if(graph[k][j])                in[j]--;        in[k] = -1;        tmp++;    }    return (tmp == cnt_num) ? 1 : 0;}int main() {    int i,j,u,v,t;    scanf("%d",&t);    while(t--){        scanf("%d%d",&n,&m);        clr(head,-1); clr(step,0); clr(belong,0); clr(in,0);        clr(graph,false); clr(in_stack,false);        num = cnt = cnt_num = kk = count_node = 0;        FOR(i,0,m){            scanf("%d%d",&u,&v);            e[cnt].v  = v;            e[cnt].nxt = head[u];            head[u] = cnt++;        }        FORE(i,1,n)            if(!step[i])                Tarjan(i);        FORE(i,1,n)            for(j = head[i]; j != -1; j = e[j].nxt)                if(belong[i] != belong[e[j].v]){                    graph[belong[i]][belong[e[j].v]] = true;                    in[belong[e[j].v]] = 1;                }        if(topo())            cout<<"Yes"<<endl;        else            cout<<"No"<<endl;    }    return 0;}