• 图论--2-SAT--Tarjan连通分量+拓扑排序O(N+M)模板


    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <algorithm>
    #define MAXN 2000+10
    #define MAXM 400000
    #define INF 1000000
    using namespace std;
    vector<int> G[MAXN];
    int low[MAXN], dfn[MAXN];
    int dfs_clock;
    int sccno[MAXN], scc_cnt;
    stack<int> S;
    bool Instack[MAXN];
    int N, M;
    void init()
    {
    	for(int i = 0; i < 2*N; i++) G[i].clear();
    }
    void getMap()
    {
    	int a, b, c;
    	char op[10];
    	while(M--)
    	{
    		scanf("%d%d%d%s", &a, &b, &c, op);
    		if(op[0]=='A') //表示and
            {
                if(c==1) //表示上述关系为真,即AB为真
                {
                    G[N+a].push_back(a);
                    G[N+b].push_back(b);
                }
                else
                {
                    G[a].push_back(b+N);
                    G[b].push_back(a+N);
                }
            }
            else if(op[0]=='O')
            {
                if(c==1)
                {
                    G[b + N].push_back(a);
    				G[a + N].push_back(b);
                }
                else
                {
                    G[a].push_back(a+N);
                    G[b].push_back(b+N);
                }
            }
            else if(op[0]=='X')
            {
                if(c==1)
                {
                    G[a].push_back(b+N);
                    G[a+N].push_back(b);
                    G[b+N].push_back(a);
                    G[b].push_back(a+N);
                }
                else
                {
                    G[a].push_back(b);
    				G[b].push_back(a);
    				G[a + N].push_back(b + N);
    				G[b + N].push_back(a + N);
                }
            }
    	}
    }
    void tarjan(int u, int fa)
    {
    	int v;
    	low[u] = dfn[u] = ++dfs_clock;
    	S.push(u);
    	Instack[u] = true;
    	for(int i = 0; i < G[u].size(); i++)
    	{
    		v = G[u][i];
    		if(!dfn[v])
    		{
    			tarjan(v, u);
    			low[u] = min(low[u], low[v]);
    		}
    		else if(Instack[v])
    		low[u] = min(low[u], dfn[v]);
    	}
    	if(low[u] == dfn[u])
    	{
    		scc_cnt++;
    		for(;;)
    		{
    			v = S.top(); S.pop();
    			Instack[v] = false;
    			sccno[v] = scc_cnt;
    			if(v == u) break;
    		}
    	}
    }
    void find_cut(int l, int r)
    {
    	memset(low, 0, sizeof(low));
    	memset(dfn, 0, sizeof(dfn));
    	memset(sccno, 0, sizeof(sccno));
    	memset(Instack, false, sizeof(Instack));
    	dfs_clock = scc_cnt = 0;
    	for(int i = l; i <= r; i++)
    	if(!dfn[i]) tarjan(i, -1);
    }
    void solve()
    {
    	for(int i = 0; i < N; i++)
    	{
    		if(sccno[i] == sccno[i + N])
    		{
    			printf("NO
    ");
    			return ;
    		}
    	}
    	printf("YES
    ");
    }
    int main()
    {
    	while(scanf("%d%d", &N, &M) != EOF)
    	{
    		init();
    		getMap();
    		find_cut(0, 2*N-1);
    		solve();
    	}
    	return 0;
    }
    
    
    
  • 相关阅读:
    MySQL语句进行分组后的含有字段拼接方法
    架构基础
    自动化测试框架比较
    分布式系统中的概念--第一篇 一致性协议、一致性模型、拜占庭问题、租约
    如果两个对象具有相同的哈希码,但是不相等的,它们可以在HashMap中同时存在吗?
    分布式系统常用思想和技术总结(转)
    常用的Hash算法
    Sonar + Jacoco,强悍的UT, IT 双覆盖率统计(转)
    AWK处理日志入门(转)
    内存管理
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798598.html
Copyright © 2020-2023  润新知