int main() { int ap; int x[2]; char y[2]; int i; ascii['w'] = 1; ascii['h'] = 0; while (scanf("%d %d", &n, &ap) != EOF) { if (n == 0 && ap == 0) break; for (i = 0; i < n*2; i++) { v[i].c = 0; v[i].tf = 0; } for (i = 0; i < ap; i++) { scanf("%d%c %d%c", x, y, x+1, y+1); x[0] = (x[0] << 1) + ascii[y[0]]; x[1] = (x[1] << 1) + ascii[y[1]]; ADD_EDGE(x[0]^1, x[1]); ADD_EDGE(x[1]^1, x[0]); } ADD_EDGE(0,1); if (solve() == 0) { puts("bad luck"); } else { for (i = 2; i < n*2; i+=2) { if(i != 2) printf(" "); if(v[i].tf == v[0].tf) printf("%dw", i/2); else printf("%dh", i/2); } puts(""); } }/* while */ #ifndef ONLINE_JUDGE system("pause"); #endif return 0; }
void testDFS() { ADD_EDGE(1,2); ADD_EDGE(1,4); ADD_EDGE(2,5); ADD_EDGE(3,5); ADD_EDGE(3,6); ADD_EDGE(4,2); ADD_EDGE(5,4); ADD_EDGE(6,6); nVertex = 6; DFS(); printf("visiting sequence (image22-4 in CLRS:)\n"); for(int i=0; i<time; i++) { printf("%c ", sequence[i]+'u'); } }
PerfectMatching::EdgeId PerfectMatching::AddEdge(NodeId _i, NodeId _j, REAL cost) { if (_i<0 || _i>=node_num || _j<0 || _j>node_num || _i==_j) { printf("wrong node id's! (%d,%d)\n", _i, _j); exit(1); } if (edge_num >= edge_num_max) ReallocateEdges(); Node* i = nodes + _i; Node* j = nodes + _j; Edge* a = edges + edge_num; ADD_EDGE(i, a, 0); ADD_EDGE(j, a, 1); a->head0[0] = j; a->head0[1] = i; a->slack = cost*COST_FACTOR; PriorityQueue<REAL>::ResetItem(a); return edge_num ++; }
void testTopologicalSort() { ADD_EDGE(1,2); ADD_EDGE(1,8); ADD_EDGE(2,3); ADD_EDGE(2,8); ADD_EDGE(3,4); ADD_EDGE(3,6); ADD_EDGE(4,5); ADD_EDGE(5,6); ADD_EDGE(7,8); nVertex = 6; DFS(); char *text[] = {"undershot", "pant", "belt", "shirt", "tie", "jacket", "socks", "shoes", "watch"}; printf("visiting sequence (image22-7 in CLRS:)\n"); for(int i=0; i<time; i++) { printf("%s ", text[ sequence[i]%nVertex ]); } printf("\nTopological sort result:\n"); std::map<int,int> m; //reverse finish time -> vertex id for(int i=0; i<nVertex; i++) m[ -f[i] ] = i; for(std::map<int,int>::iterator it=m.begin(); it!=m.end(); ++it) { printf("%s ", text[ it->second%nVertex ]); } }
GeomTree::GeomTree(const int numVerts, const int numTris, const std::vector<vector3f> &vertices, const Uint16 *indices, const unsigned int *triflags) : m_numVertices(numVerts) , m_numTris(numTris) , m_vertices(vertices) { assert(static_cast<int>(vertices.size()) == m_numVertices); Profiler::Timer timer; timer.Start(); const int numIndices = numTris * 3; m_indices.reserve(numIndices); for (int i = 0; i < numIndices; ++i) { m_indices.push_back(indices[i]); } m_triFlags.reserve(numTris); for (int i = 0; i < numTris; ++i) { m_triFlags.push_back(triflags[i]); } m_aabb.min = vector3d(FLT_MAX,FLT_MAX,FLT_MAX); m_aabb.max = vector3d(-FLT_MAX,-FLT_MAX,-FLT_MAX); // activeTris = tris we are still trying to put into leaves std::vector<int> activeTris; activeTris.reserve(numTris); // So, we ignore tris with flag >= 0x8000 for (int i=0; i<numTris; i++) { if (triflags[i] >= IGNORE_FLAG) continue; activeTris.push_back(i*3); } typedef std::map< std::pair<int,int>, int > EdgeType; EdgeType edges; #define ADD_EDGE(_i1,_i2,_triflag) \ if ((_i1) < (_i2)) edges[std::pair<int,int>(_i1,_i2)] = _triflag; \ else if ((_i1) > (_i2)) edges[std::pair<int,int>(_i2,_i1)] = _triflag; // eliminate duplicate vertices { std::vector<Uint32> xrefs; nv::Weld<vector3f> weld; weld(m_vertices, xrefs); m_numVertices = m_vertices.size(); //Output("--- %d vertices welded\n", count - newCount); // Remap faces. const Uint32 faceCount = numTris; for (Uint32 f = 0; f < faceCount; f++) { const Uint32 idx = (f * 3); m_indices[idx+0] = xrefs.at(m_indices[idx+0]); m_indices[idx+1] = xrefs.at(m_indices[idx+1]); m_indices[idx+2] = xrefs.at(m_indices[idx+2]); } } // Get radius, m_aabb, and merge duplicate edges m_radius = 0; for (int i=0; i<numTris; i++) { const unsigned int triflag = m_triFlags[i]; if (triflag < IGNORE_FLAG) { const int vi1 = m_indices[3*i+0]; const int vi2 = m_indices[3*i+1]; const int vi3 = m_indices[3*i+2]; ADD_EDGE(vi1, vi2, triflag); ADD_EDGE(vi1, vi3, triflag); ADD_EDGE(vi2, vi3, triflag); vector3d v[3]; v[0] = vector3d(m_vertices[vi1]); v[1] = vector3d(m_vertices[vi2]); v[2] = vector3d(m_vertices[vi3]); m_aabb.Update(v[0]); m_aabb.Update(v[1]); m_aabb.Update(v[2]); for (int j=0; j<3; j++) { const double rad = v[j].x*v[j].x + v[j].y*v[j].y + v[j].z*v[j].z; if (rad>m_radius) m_radius = rad; } } } m_radius = sqrt(m_radius); { Aabb *aabbs = new Aabb[activeTris.size()]; for (unsigned int i = 0; i < activeTris.size(); i++) { const vector3d v1 = vector3d(m_vertices[m_indices[activeTris[i] + 0]]); const vector3d v2 = vector3d(m_vertices[m_indices[activeTris[i] + 1]]); const vector3d v3 = vector3d(m_vertices[m_indices[activeTris[i] + 2]]); aabbs[i].min = aabbs[i].max = v1; aabbs[i].Update(v2); aabbs[i].Update(v3); } //int t = SDL_GetTicks(); m_triTree.reset(new BVHTree(activeTris.size(), &activeTris[0], aabbs)); delete[] aabbs; } //Output("Tri tree of %d tris build in %dms\n", activeTris.size(), SDL_GetTicks() - t); m_numEdges = edges.size(); m_edges.resize( m_numEdges ); // to build Edge bvh tree with. m_aabbs.resize( m_numEdges ); int *edgeIdxs = new int[m_numEdges]; int pos = 0; typedef EdgeType::iterator MapPairIter; for (MapPairIter i = edges.begin(), iEnd = edges.end(); i != iEnd; ++i, pos++) { // precalc some j**z const std::pair<int, int> &vtx = (*i).first; const int triflag = (*i).second; const vector3f &v1 = m_vertices[vtx.first]; const vector3f &v2 = m_vertices[vtx.second]; vector3f dir = (v2-v1); const float len = dir.Length(); dir *= 1.0f/len; m_edges[pos].v1i = vtx.first; m_edges[pos].v2i = vtx.second; m_edges[pos].triFlag = triflag; m_edges[pos].len = len; m_edges[pos].dir = dir; edgeIdxs[pos] = pos; m_aabbs[pos].min = m_aabbs[pos].max = vector3d(v1); m_aabbs[pos].Update(vector3d(v2)); } //t = SDL_GetTicks(); m_edgeTree.reset(new BVHTree(m_numEdges, edgeIdxs, &m_aabbs[0])); delete [] edgeIdxs; //Output("Edge tree of %d edges build in %dms\n", m_numEdges, SDL_GetTicks() - t); timer.Stop(); //Output(" - - GeomTree::GeomTree took: %lf milliseconds\n", timer.millicycles()); }
GeomTree::GeomTree(int numVerts, int numTris, float *vertices, Uint16 *indices, unsigned int *triflags) : m_numVertices(numVerts) , m_numTris(numTris) { m_vertices = vertices; m_indices = indices; m_triFlags = triflags; m_aabb.min = vector3d(FLT_MAX,FLT_MAX,FLT_MAX); m_aabb.max = vector3d(-FLT_MAX,-FLT_MAX,-FLT_MAX); // activeTris = tris we are still trying to put into leaves std::vector<int> activeTris; /* So, we ignore tris with flag >= 0x8000 */ for (int i=0; i<numTris; i++) { if (triflags[i] >= IGNORE_FLAG) continue; activeTris.push_back(i*3); } std::map< std::pair<int,int>, int > edges; #define ADD_EDGE(_i1,_i2,_triflag) \ if ((_i1) < (_i2)) edges[std::pair<int,int>(_i1,_i2)] = _triflag; \ else if ((_i1) > (_i2)) edges[std::pair<int,int>(_i2,_i1)] = _triflag; // eliminate duplicate vertices for (int i=0; i<numVerts; i++) { vector3d v = vector3d(&m_vertices[3*i]); for (int j=i+1; j<numVerts; j++) { vector3d v2 = vector3d(&m_vertices[3*j]); if (v2.ExactlyEqual(v)) { for (int k=0; k<numTris*3; k++) { if ((indices[k] == j) && (triflags[k/3] < 0x8000)) indices[k] = i; } } } } /* Get radius, m_aabb, and merge duplicate edges */ m_radius = 0; for (int i=0; i<numTris; i++) { const unsigned int triflag = m_triFlags[i]; if (triflag < IGNORE_FLAG) { int vi1 = 3*m_indices[3*i]; int vi2 = 3*m_indices[3*i+1]; int vi3 = 3*m_indices[3*i+2]; ADD_EDGE(vi1, vi2, triflag); ADD_EDGE(vi1, vi3, triflag); ADD_EDGE(vi2, vi3, triflag); vector3d v[3]; v[0] = vector3d(&m_vertices[vi1]); v[1] = vector3d(&m_vertices[vi2]); v[2] = vector3d(&m_vertices[vi3]); m_aabb.Update(v[0]); m_aabb.Update(v[1]); m_aabb.Update(v[2]); for (int j=0; j<3; j++) { double rad = v[j].x*v[j].x + v[j].y*v[j].y + v[j].z*v[j].z; if (rad>m_radius) m_radius = rad; } } } m_radius = sqrt(m_radius); Aabb *aabbs = new Aabb[activeTris.size()]; for (unsigned int i=0; i<activeTris.size(); i++) { vector3d v1 = vector3d(&m_vertices[3*m_indices[activeTris[i]]]); vector3d v2 = vector3d(&m_vertices[3*m_indices[activeTris[i]+1]]); vector3d v3 = vector3d(&m_vertices[3*m_indices[activeTris[i]+2]]); aabbs[i].min = aabbs[i].max = v1; aabbs[i].Update(v2); aabbs[i].Update(v3); } //int t = SDL_GetTicks(); m_triTree = new BVHTree(activeTris.size(), &activeTris[0], aabbs); delete [] aabbs; //Output("Tri tree of %d tris build in %dms\n", activeTris.size(), SDL_GetTicks() - t); m_numEdges = edges.size(); m_edges = new Edge[m_numEdges]; // to build Edge bvh tree with. aabbs = new Aabb[m_numEdges]; int *edgeIdxs = new int[m_numEdges]; int pos = 0; for (std::map< std::pair<int,int>, int >::iterator i = edges.begin(); i != edges.end(); ++i, pos++) { // precalc some j**z const std::pair<int, int> &vtx = (*i).first; const int triflag = (*i).second; vector3d v1 = vector3d(&m_vertices[vtx.first]); vector3d v2 = vector3d(&m_vertices[vtx.second]); vector3d dir = (v2-v1); double len = dir.Length(); dir *= 1.0/len; m_edges[pos].v1i = vtx.first; m_edges[pos].v2i = vtx.second; m_edges[pos].triFlag = triflag; m_edges[pos].len = float(len); m_edges[pos].dir = vector3f(float(dir.x), float(dir.y), float(dir.z)); edgeIdxs[pos] = pos; aabbs[pos].min = aabbs[pos].max = v1; aabbs[pos].Update(v2); } //t = SDL_GetTicks(); m_edgeTree = new BVHTree(m_numEdges, edgeIdxs, aabbs); delete [] aabbs; delete [] edgeIdxs; //Output("Edge tree of %d edges build in %dms\n", m_numEdges, SDL_GetTicks() - t); }