POJ 3207 解题报告

这是我遇到的第一道2-SAT问题。将两条边记为x和y。如果x和y相交,那么x和y不能同时在环外(即都取true),也不能同时在环内(即都取false)。前者,我们有x->~y, y -> ~x;后者,我们有~x->y, ~y -> x。

这道题只问2-SAT是否能满足,而没有问怎样才能满足,所以只需要求强连通子图部分,而不需要逆向拓扑排序部分(这部分目前还不是很懂)。

thestoryofsnow3207Accepted1236K79MSC++3532B
/* 
ID: thestor1 
LANG: C++ 
TASK: poj3207 
*/
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <cassert>

using namespace std;

// const int MAXN = 1000;
const int MAXM = 500;

class Edge
{
public:
	int a, b;
	Edge() {}
	Edge(int a, int b) : a(a), b(b) {}
	inline bool operator< (const Edge &rhs) const 
	{
		return a < rhs.a || (a == rhs.a && b < rhs.b);
	}
};

bool isundefined(int u, vector<int> &indexes)
{
	return indexes[u] < 0;
}

void strongconnect(int u, int &index, vector<int> &indexes, vector<int> &lowlinks, int &SCCNO, vector<int> &sccnos, stack<int> &S, vector<bool> &onStack, const vector<vector<int> > &adjs)
{
	// Set the depth index for u to the smallest unused index
	indexes[u] = index;
	lowlinks[u] = index;
	index++;

	S.push(u);
	onStack[u] = true;

	 // Consider successors of u
	for (int i = 0; i < adjs[u].size(); ++i)
	{
		int v = adjs[u][i];
		if (isundefined(v, indexes))
		{
			// Successor v has not yet been visited; recurse on it
			strongconnect(v, index, indexes, lowlinks, SCCNO, sccnos, S, onStack, adjs);
			lowlinks[u] = min(lowlinks[u], lowlinks[v]);
		}
		else if (onStack[v])
		{
			// Successor v is in stack S and hence in the current SCC
			lowlinks[u] = min(lowlinks[u], lowlinks[v]);	
		}
	}

	// If u is a root node, pop the stack and generate an SCC
	if (indexes[u] == lowlinks[u])
	{
		// start a new strongly connected component
		while (true)
		{
			int v = S.top();
			S.pop();
			onStack[v] = false;

			// add v to current strongly connected component
			sccnos[v] = SCCNO;

			if (v == u)
			{
				break;
			}
		}

		SCCNO++;
	}
}


// Tarjan's strongly connected components algorithm
// See http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
void tarjan(const int N, const vector<vector<int> > &adjs, int &SCCNO, vector<int> &sccnos)
{
	int index = 0;
	vector<int> indexes(N, -1);

	vector<int> lowlinks(N, -1);

	stack<int> S;
	vector<bool> onStack(N, false);
	
	for (int u = 0; u < N; ++u)
	{
		if (isundefined(u, indexes))
		{
			strongconnect(u, index, indexes, lowlinks, SCCNO, sccnos, S, onStack, adjs);
		}
	}

}

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	Edge edges[MAXM];
	for (int i = 0; i < m; ++i)
	{
		scanf("%d%d", &edges[i].a, &edges[i].b);
		if (edges[i].a > edges[i].b)
		{
			int t = edges[i].a;
			edges[i].a = edges[i].b;
			edges[i].b = t;
		}
	}
	sort(edges, edges + m);
	// in the 2-SAT sense, if i is x, then i + n is ~x
	vector<vector<int> > adjs(2 * m, std::vector<int>());
	for (int i = 0; i < m; ++i)
	{
		for (int j = i + 1; j < m && edges[j].a < edges[i].b; ++j)
		{
			if (edges[j].b > edges[i].b)
			{
				// i interleaves with j, then x (i) and y (j) can not both be true
				// then if x is true, y should be false (that is, ~y is true)
				//  x -> ~y
				adjs[i].push_back(j + m);
				adjs[j].push_back(i + m);
				adjs[i + m].push_back(j);
				adjs[j + m].push_back(i);	
			}
		}
	}

	int SCCNO = 0;
	vector<int> sccnos(2 * m, -1);
	tarjan(2 * m, adjs, SCCNO, sccnos);

	bool conflict = false;
	for (int i = 0; i < m; ++i)
	{
		// if both x and ~x are true, we have conflicts here
		if (sccnos[i] == sccnos[i + m])
		{
			conflict = true;
			break;
		}
	}

	if (conflict)
	{
		printf("the evil panda is lying again\n");
	}
	else
	{
		printf("panda is telling the truth...\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值