private static ZDDNode CheckTerminal(ZDDNode n_hat, int i, int x, State state) { Edge edge = state.graph.GetEdgeList()[i - 1]; if(x == 1) { // 辺でつないだときに,それぞれの連結成分の要素数が4超え(フォーセルズ的に破綻)したら if(n_hat.compCount[n_hat.comp[edge.src]] + n_hat.compCount[n_hat.comp[edge.dest]] > 4) { // 同じ連結成分ならセーフ if(n_hat.comp[edge.src] != n_hat.comp[edge.dest]) { return ZDDNode.ZeroTerminal; } } if(n_hat.mate[edge.src] != 0 || n_hat.mate[edge.dest] != 0) { int src = n_hat.mate[edge.src]; int dest = n_hat.mate[edge.dest]; if(src == 0) { src = edge.src; } if(dest == 0) { dest = edge.dest; } foreach(Edge ed in state.graph.GetEdgeList()) { if(ed.compare(src, dest)) { return ZDDNode.ZeroTerminal; } } } } else { // 四角のブロックはループさせる if(n_hat.comp[edge.src] == n_hat.comp[edge.dest]) { return ZDDNode.ZeroTerminal; } } ZDDNode n_prime = n_hat.MakeCopy(); UpdateInfo(n_prime, i, x, state); int[] src_dest = new int[] { edge.src, edge.dest }; bool check = false; // フロンティアに関して foreach(int u in src_dest) { // フロンティアを抜ける if(!state.F[i].Contains(u)) { if(n_prime.compCount[n_prime.comp[u]] < 4) { check = false; foreach(int f in state.F[i]) { if(n_prime.comp[f] == n_prime.comp[u]) { check = true; } } if(!check) { return ZDDNode.ZeroTerminal; } } } } // 最後の辺まで処理を終えたなら if(i == state.graph.GetEdgeList().Count) { return ZDDNode.OneTerminal; } // 0終端か1終端かまだ判定がつかない中継ノード return null; }