【算法练习】POJ - 3648 Wedding (2-STA)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/pengwill97/article/details/82080667

题意

题解

代码

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef double db;
typedef long long ll;
typedef unsigned long long ull;
const int nmax = 1e6+7;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
const ull p = 67;
const ull MOD = 1610612741;
int head[nmax], tot, tot2, head2[nmax];
int dfn[nmax], low[nmax], color[nmax], ss[nmax], st, scc, dfs_clock;
int in[nmax], opp[nmax], ban[nmax];
bool instack[nmax];
queue<int> q;
struct edge{
    int to, nxt;
}e[nmax<<1], e2[nmax<<1];
void add_edge(int u, int v) {
    e[tot].to = v;
    e[tot].nxt = head[u];
    head[u] = tot++;
}
void add_edge2(int u, int v) {
    e2[tot2].to = v;
    e2[tot2].nxt = head2[u];
    head2[u] = tot2++;
}
void init() {
    memset(head, -1, sizeof head);
    memset(head2, -1, sizeof head2);
    memset(dfn, 0, sizeof dfn);
    memset(low, 0, sizeof low);
    memset(color, 0, sizeof color);
    memset(ban, 0 ,sizeof ban);
    memset(in, 0, sizeof in);
    memset(opp, 0, sizeof opp);
    st = scc = dfs_clock = tot2 = tot = 0;
}
void topo(int u) {
    q.push(u);
    in[u] = -1;
    for(int i = head2[u] ; i != -1; i = e2[i].nxt) {
        int v = e2[i].to;
        in[v] -- ;
        if(!in[v])
            topo(v);
    }
}
void tarjan(int u) {
    low[u] = dfn[u] = ++ dfs_clock;
    ss[st++] = u;
    instack[u] = true;
    for(int i = head[u] ; i != -1; i = e[i].nxt) {
        int v = e[i].to;
        if(!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if(instack[v]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
    if(low[u] == dfn[u]) {
        scc ++;
        int tmp;
        for(;;) {
            tmp = ss[--st];
            color[tmp] = scc;
            instack[tmp] = false;
            if(tmp == u)
                break;
        }
    }
}
int n, m;
int main(){
    while(scanf("%d %d", &n, &m)!= EOF) {
        if(n == 0 && m == 0)
            break;
        init();
        int u, v, ou, ov;
        char cu, cv;
        for(int i = 1; i <= m; ++i) {
            scanf("%d%c%d%c", &u, &cu, &v, & cv);
            if(cu == 'h')
                u = (u << 1) +1;
            else
                u = (u << 1);
            ou = u ^ 1;
            if(cv == 'h')
                v = (v << 1) + 1;
            else
                v = (v << 1);
            ov =  v ^ 1;
            add_edge(u, ov);
            add_edge(v, ou);
        }
        add_edge(0, 1);
        for(int i = 0; i < 2 * n; ++i) {
            if(!dfn[i])
                tarjan(i);
        }
        bool isok = true;
        for(int i = 0; i < 2 * n; i += 2) {
            if(color[i] == color[i + 1]) {
                isok = false;
                break;
            }
        }
        if(!isok) {
            printf("bad luck\n");
            continue;
        }
        for(int u = 0; u < 2 * n; ++u) {
            for(int i = head[u]; i != -1; i = e[i].nxt) {
                int v = e[i].to;
                if(color[v] != color[u]){
                    add_edge2(color[v], color[u]);
                    in[color[u]] ++;
                }
            }
            opp[color[u]] = color[u^1];
        }
        for(int i = 0; i < 2 * n; ++i) {
            if(!in[i])
                topo(i);
        }
        while(!q.empty()) {
            int now = q.front();
            q.pop();
            if(!ban[now]) {
                ban[now] = 1;
                ban[opp[now]] = 2;
            }
        }
        int tar = ban[color[0]];
        for(int i = 2; i < 2 * n; ++ i) {
            if(ban[color[i]] == tar) {
                if(i & 1) {
                    printf("%dh ", i >> 1);
                } else {
                    printf("%dw ", i >> 1);
                }
            }
        }
        printf("\n");

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/pengwill97/article/details/82080667