Cod sursa(job #874652)

Utilizator vlad_DVlad Dumitriu vlad_D Data 9 februarie 2013 09:50:53
Problema Party Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

namespace tsat {
#define vii vector<vector<int> >
#define vi vector<int>
#define pb(a) push_back(a)
int N;  // 2 * N
vii G, GT;  // implicatii si transpusu
vi val;  // valorile la sf.
vi st, viz;  // stack si vizitat
int no_sol; // daca nu este solutie.
inline int neg(int n) {
  if (n <= N) return n + N;
  else return n - N;
}
inline void sau(int a, int b) {
  // transforma in implicatii.
  G[neg(a)].pb(b); G[neg(b)].pb(a);
  GT[b].pb(neg(a)); GT[a].pb(neg(b));
}
inline void dfs(int nod) {
  viz[nod] = 1;
  for (int i = 0; i < G[nod].size(); ++i) {
    int nod2 = G[nod][i];
    if (!viz[nod2]) dfs(nod2);
  }
  st.pb(nod);
}
inline void dfs_t(int nod) {
  viz[nod] = 1;
  if (val[nod]) no_sol = 1;  // nu e solutie.
  val[nod] = 0; val[neg(nod)] = 1;
  for (int i = 0; i < GT[nod].size(); ++i) {
    int nod2 = GT[nod][i];
    if (!viz[nod2]) dfs_t(nod2);
  }
}
int two_sat() {
  viz.assign(2*N+1, 0);
  for (int i = 1; i <= 2 * N; ++i) 
    if (!viz[i]) dfs(i);
  viz.assign(2*N+1, 0);
  for (int i = st.size() - 1; i >= 0; --i) {
    if (!viz[st[i]] && !viz[neg(st[i])]) dfs_t(st[i]);
  }
  return no_sol == 0;
}
void clear() {
  N = 0;
  G.clear(); GT.clear(); val.clear(); st.clear(); viz.clear(); no_sol = 0;
}
void adapt();  // function to implement, make sure you use in::.
} // namespace tsat

namespace in { 
int N, M;
int rel[1024][3];
}  // namespace for the input.

using namespace in;
int main() {
  freopen("party.in", "r", stdin);
  freopen("party.out", "w", stdout);
  scanf("%d %d", &N, &M);
  for (int i = 1; i <= M; ++i) scanf("%d %d %d", &rel[i][0], &rel[i][1], &rel[i][2]);
  tsat::adapt();
  tsat::two_sat();
  int total = 0;
  for (int i = 1; i <= N; ++i) if (tsat::val[i]) ++total;
  printf("%d\n", total);
  for (int i = 1; i <= N; ++i) if (tsat::val[i])
    printf("%d\n", i);
  return 0;
}

void tsat::adapt() {
  clear();
  N = in::N;
  G.resize(2 * N + 1); GT.resize(2 * N + 1);
  val.resize(2 * N + 1);
  for (int i = 1; i <= in::M; ++i) {
    switch(rel[i][2]) {
      case 0:
      sau(rel[i][0], rel[i][1]);
      break;
      case 1:
      sau(rel[i][0], neg(rel[i][1]));
      break;
      case 2:
      sau(neg(rel[i][0]), rel[i][1]);
      break;
      case 3:
      sau(neg(rel[i][0]), neg(rel[i][1]));
      break;
    }
  }
}