zoukankan      html  css  js  c++  java
  • 图论--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;
    }
    
    
    
  • 相关阅读:
    spring boot 2 统一异常处理
    spring boot 2.0.4 Redis缓存配置
    windows下consul利用json文件注册服务
    docker安装portainer
    Docker 清理命令
    git command line 提交代码
    java应用健康检查
    springboot @Value获取值为空,解决办法
    解决You have new mail in /var/spool/mail/root提示
    kafka之kafka的伪分布式安装
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798598.html
Copyright © 2011-2022 走看看