SGU 101. Domino

debug得我蛋都疼了。。。

本题的做法是,建立一个含有7个点的无向图(0...6),如果存在一个骨牌(a,b),那么添加边{a,b}。于是问题转化为,寻找关于这个图的一个欧拉路径。

两个非常容易出错的问题:
1. 有没有可能出现自环?任何与图有关的问题都要考虑这个问题,不然一定被恶心到死。
2. 是否是一个连通图?

写的很恶心,很长,但是AC了就行。知足常乐哈~

#include <algorithm>
#include <cstdio>
#include <vector>
#include <cassert>
using namespace std;

int abs(int i) {
  return i < 0 ?  -i : i;
}

//=========================================================================
struct Domino {
  int a, b;
  char direction;
  int id;
};

Domino setDomino(int a, int b, char direction, int id) {
  Domino d;
  d.a = a;
  d.b = b;
  d.direction = direction;
  d.id = id;
  return d;
}


struct EdgeData {
  char color;
  int id;
  char direction;
  // int dominoID;
};

EdgeData setEdgeData(char color, int id, char direction) {
  EdgeData x;
  x.color = color;
  x.id = id;
  x.direction = direction;
  return x;
}


struct Edge {
  int end;
  Edge* next;
  EdgeData data;
};

typedef Edge *EdgePointer;




struct Graph {
  vector<EdgePointer> vs;

  void init(int pointNum) {
    vs.resize(pointNum + 2);
    for (int i = 0; i < vs.size(); ++i) { vs[i] = NULL; }

  }

  EdgePointer newEdge() {
    return new Edge;
  }

  void add(int st, int ed, EdgeData data) {
    EdgePointer e = newEdge();

    e->end = ed;
    e->next = vs[st];
    e->data = data;
    vs[st] = e;
  }

  EdgePointer getFirstEdge(int i) {
    return vs[i];
  }


};


//====================================================================================

Graph G;
int N;
vector<int> dTable;
vector<int> oddPIds;
vector<int> evenPIds;
int beginPoint;
vector<Domino> resultList;

//====================================================================================



void enterPoint(int pId) {
  EdgePointer it = G.getFirstEdge(pId);
  for (; it != NULL; it = it->next) {
    if (it->data.color == 'B') continue;
    it->data.color = 'B';
    for (EdgePointer tmp = G.getFirstEdge(it->end); tmp; tmp = tmp->next) {
      if (tmp->data.id == -(it->data.id)) {
        tmp->data.color = 'B';
        break;
      }
    }

    enterPoint(it->end);
    if (it->data.direction == '+')
      resultList.push_back(setDomino(pId, it->end, '+', abs(it->data.id)));
    else
      resultList.push_back(setDomino(pId, it->end, '-', abs(it->data.id)));
  }
}


void input() {
  int i;
  scanf("%d", &N);
  G.init(8);
  dTable.resize(8);
  for (i = 0; i < dTable.size(); ++i) dTable[i] = 0;

  int a, b;

  for (i = 1; i <= N; ++i) {
    scanf("%d %d", &a, &b);
    G.add(a, b, setEdgeData('W', i, '+'));
    G.add(b, a, setEdgeData('W', -i, '-'));
    dTable[a]++;
    dTable[b]++;
  }


  oddPIds.resize(0);
  evenPIds.resize(0);
  int curFather = -1;
  for (i = 0; i <= 6; ++i) {
    if (dTable[i] == 0) continue;

    if (dTable[i] % 2 == 1) {
      oddPIds.push_back(i);
    } else {
      evenPIds.push_back(i);
    }
  }


  if (oddPIds.size() == 0)
    beginPoint = evenPIds[0];
  else if (oddPIds.size() == 2)
    beginPoint = oddPIds[0];
  else
    beginPoint = -1;

}

void run() {
  input();
  if (beginPoint == -1) {
    printf("No solution\n");
    return;
  }

  resultList.resize(0);
  enterPoint(beginPoint);
  if (resultList.size() != N) {
    printf("No solution\n");
    return;
  }

  int i;
  for (i = resultList.size() - 1; i >= 0; --i)
    printf("%d %c\n", resultList[i].id, resultList[i].direction);

  assert(resultList.size() == N);
}



int main() {
  run();
  return 0;
}

你可能感兴趣的:(Algorithm,sgu)