Cod sursa(job #2975168)

Utilizator ArkinyStoica Alex Arkiny Data 5 februarie 2023 17:04:03
Problema Party Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.42 kb
#include<iostream>
#include<vector>
#include<fstream>
#include<algorithm>

using namespace std;

typedef vector<vector<int>> graph;

//Kosaraju
class SCCAlgo
{
	graph G;
	graph G_r;
	int _n;
public:
	SCCAlgo(int n)
	{
		_n = n;

		G.resize(n + 1);
		G_r.resize(n + 1);
	}
	void AddNode(int i, int j)
	{
		G[i].push_back(j);
		G_r[j].push_back(i);
	}

	vector<vector<int>> Compute()
	{
		vector<int> topsort = TopologicalSort(G);

		return ReverseDFS(G_r, topsort);
	}

private:

	vector<int> TopologicalSort(graph& g)
	{
		vector<int> visited(_n + 1);
		vector<int> nodes;

		for (int i=1;i<=_n;++i)
		{
			if (!visited[i])
			{
				DFS(i, g, visited, nodes);
			}
		}

		reverse(nodes.begin(), nodes.end());
		return nodes;
	}

	vector<vector<int>> ReverseDFS(graph& g, vector<int> topsort)
	{
		vector<vector<int>> scc;
		vector<int> visited(_n + 1);

		for (auto& node : topsort)
		{
			if (!visited[node])
			{
				scc.push_back(vector<int>());
				DFS(node, g, visited, scc.back());
			}
		}
		return scc;
	}

	void DFS(int node, graph& g, vector<int>& visited, vector<int>& resulting_nodes)
	{
		visited[node] = 1;
		for (auto& neigh : g[node])
		{
			if (!visited[neigh])
			{
				DFS(neigh, g, visited, resulting_nodes);
			}
		}
		resulting_nodes.push_back(node);
	}
	
};

class SAT2
{
	graph G;
	int _n;
public:
	SAT2(int n)
	{
		_n = n * 2;
		G.resize(_n + 1);
	}

	void AddRelation(int x, int y)
	{
		x = normalize(x);
		y = normalize(y);

		int neg_x = negation(x);
		int neg_y = negation(y);

		G[neg_x].push_back(y);
		G[neg_y].push_back(x);
	}

	vector<int> Compute()
	{
		vector<int> mapping;

		mapping.resize(_n + 1);
		SCCAlgo sccAlgo(_n);

		for (int i = 1; i <= _n; ++i)
		{
			for (auto& j : G[i])
			{
				sccAlgo.AddNode(i, j);
			}
		}

		auto sccs = sccAlgo.Compute();

		for (int i = 0; i < sccs.size(); ++i)
		{
			for (auto& node : sccs[i])
			{
				mapping[node] = i + 1;
			}
		}

		for (int i = 1; i <= _n / 2; ++i)
		{
			if (mapping[i] == mapping[negation(i)])
			{
				return {};
			}
		}

		vector<int> solution;
		solution.resize(_n / 2 + 1);

		for (int i = 0; i < solution.size(); ++i)
		{
			solution[i] = -1;
		}

		for (int i = 0; i < sccs.size(); ++i)
		{
			for (auto& node : sccs[i])
			{
				if (node > _n / 2)
				{
					if (solution[negation(node)] == -1)
					{
						solution[negation(node)] = 1;
					}
				}
				else
				{
					if (solution[node] == -1)
					{
						solution[node] = 0;
					}
				}
			}
		}
		return solution;
	}

	int normalize(int x)
	{
		if (x < 0)
		{
			return _n + x + 1;
		}
		return x;
	}

	int negation(int x)
	{
		return _n - x + 1;
	}
};

int main()
{

	int N, M;
	ifstream in("party.in");
	ofstream out("party.out");

	in >> N >> M;

	SAT2 sat2(N);

	for (int i = 1; i <= M; ++i)
	{
		int x, y, op;

		in >> x >> y >> op;

		if (op == 0)
		{
			sat2.AddRelation(x, y);
		}
		else if (op == 1)
		{
			sat2.AddRelation(x, -y);
		}
		else if (op == 2)
		{
			sat2.AddRelation(-x, y);
		}
		else
		{
			sat2.AddRelation(-x, -y);
		}

		
	}

	auto solution = sat2.Compute();
	int nr = 0;
	for (int i = 1; i <= N; ++i)
	{
		if (solution[i])
		{
			nr += 1;
		}
	}
	out << nr << "\n";
	for (int i = 1; i <= N; ++i)
	{
		if (solution[i])
		{
			out << i << "\n";
		}
	}


	return 0;
}