【HIT1917】 Peaceful Commission

来源:互联网 发布:淘宝有什么好看的衣服 编辑:程序博客网 时间:2024/06/10 01:18

Solution

2-sat模板题,但是暴力也可以过,还可以过HDU上的字典序。
标解是 缩点+拓扑 http://blog.csdn.net/jarjingx/article/details/8521690
Tips:不要再新的HIT上交,要去旧的上交

CODE

/* * @key word:2-sat * @tesed on:HIT 1917 50ms * @Author: lhq  * @Date: 2017-08-29 20:32:14  * @Last Modified by: lhq * @Last Modified time: 2017-08-30 18:12:26 */#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <cstdlib>using namespace std;const int MAXN = 16010, MAXM = 40010;int Head[MAXN], Head2[MAXN], ind[MAXN], tot, tot2;int dfn[MAXN], low[MAXN], scc[MAXN], f[MAXN], id, tim;int stk[MAXN], top;int color[MAXN], n, m;bool vis[MAXN];struct Edge{    int v, next;} edge[MAXM], edge2[MAXM];void addedge(int x, int y){    edge[tot] = (Edge){y, Head[x]};    Head[x] = tot++;}void addedge2(int x, int y){    edge2[tot2] = (Edge){y, Head2[x]};    Head2[x] = tot2++;    ind[y]++;}void tarjan(int u){    dfn[u] = low[u] = ++tim;    stk[++top] = u;    vis[u] = true;    for (int i = Head[u]; i != -1; i = edge[i].next)    {        int v = edge[i].v;        if (!dfn[v])        {            tarjan(v);            low[u] = min(low[u], low[v]);        }        else if (vis[v])            low[u] = min(low[u], dfn[v]);    }    if (low[u] == dfn[u])    {        id++;        while (true)        {            int v = stk[top--];            vis[v] = false;            scc[v] = id;            if (u == v)                break;        }    }}void buildDag(){    for (int u = 0; u < n + n; u++)        for (int i = Head[u]; i != -1; i = edge[i].next)        {            int v = edge[i].v;            if (scc[u] == scc[v])                continue;            addedge2(scc[v], scc[u]);        }}void topsort(){    queue<int> Q;    for (int i = 1; i <= id; i++)        if (!ind[i])            Q.push(i);    while (!Q.empty())    {        int u = Q.front();        Q.pop();        if (!color[u])            color[u] = 1, color[f[u]] = 2;        for (int i = Head2[u]; i != -1; i = edge2[i].next)        {            int v = edge2[i].v;            ind[v]--;            if (!ind[v])                Q.push(v);        }    }}void solve(){    for (int i = 0; i < n + n; i++)        if (!dfn[i])            tarjan(i);    for (int i = 0; i < n + n; i += 2)        if (scc[i] == scc[i ^ 1])        {            puts("NIE");            return;        }        else            f[scc[i]] = scc[i + 1], f[scc[i + 1]] = scc[i];    buildDag();    topsort();    for (int i = 0; i < n + n; i += 2)        if (color[scc[i]] == 1)            printf("%d\n", i + 1);        else            printf("%d\n", i + 2);}int main(){    while (scanf("%d%d", &n, &m) == 2)    {        memset(Head, -1, sizeof(Head));        memset(Head2, -1, sizeof(Head2));        memset(dfn, 0, sizeof(dfn));        memset(low, 0, sizeof(low));        memset(vis, false, sizeof(vis));        memset(ind, 0, sizeof(ind));        memset(color, 0, sizeof(color));        tot = tot2 = tim = id = top = 0;        for (int i = 1; i <= m; i++)        {            int a, b;            scanf("%d%d", &a, &b);            a--;            b--;            addedge(a, b ^ 1);            addedge(b, a ^ 1);        }        solve();    }    //system("pause");    return 0;}
原创粉丝点击