static void addOrthEdge(GraphVertex u, GraphVertex v, const std::vector<Primitive*>& vecPrimitive, std::vector<GraphVertex>& vecPredecessor, double angleThreshold, Graph& g) { u = g[u].getParent(); v = g[v].getParent(); // check if edge exists if (edge(u, v, g).second) { return; } if (!willProduceLoop(vecPredecessor, v, u, g)) { add_edge(u, v, EdgeProp(RelationEdge::RET_ORTHOGONAL), g); } else { add_edge(u, v, EdgeProp(RelationEdge::RET_ORTHOGONAL), g); // there is a path between u and v, and we added edge(u, v), so there will be loop std::vector<GraphVertex> vecLoop; GraphVertex current = u; vecLoop.push_back(current); while (vecPredecessor[current] != current) { current = vecPredecessor[current]; vecLoop.push_back(current); } int nLoopSize = vecLoop.size(); if (nLoopSize == 3) { GraphVertex opposite2 = 0; GraphVertex opposite0 = 0; bool bShare01 = findBridge(vecLoop[0], vecLoop[1], g, opposite2); bool bShare12 = findBridge(vecLoop[1], vecLoop[2], g, opposite0); if (bShare01) { addParaEdge(opposite2, vecLoop[2], vecPrimitive, vecPredecessor, angleThreshold, g); } if (bShare12) { addParaEdge(opposite0, vecLoop[0], vecPrimitive, vecPredecessor, angleThreshold, g); } } else { std::pair<GraphVertex, GraphVertex> para = findParalell(vecLoop, vecPrimitive, (nLoopSize == 4), angleThreshold); if (para.first != para.second) { addParaEdge(para.first, para.second, vecPrimitive, vecPredecessor, angleThreshold, g); } } } return; }
int main() { int test, cs, n, m, i, u, v; scanf("%d", &test); for(cs = 1; cs <= test; cs++) { scanf("%d %d", &n, &m); memset(fin, -1, sizeof(int)*n); memset(used, 0, sizeof(int)*n); for(i = nEdge = 0; i < m; i++) { scanf("%d %d", &u, &v); addEdge(u, v); } dfsTime = nComp = 0; findBridge(0, -1); memset(used, 0, sizeof(int)*n); for(i = 0; i < n; i++) { if(!used[i]) { traverse(i); nComp++; } } memset(deg, 0, sizeof(int)*nComp); for(i = 0; i < nEdge; i+=2) { if(bridge[i]) { deg[compo[from[i]]]++; deg[compo[to[i]]]++; } } for(i = m = 0; i < nComp; i++) m += (deg[i] == 1); printf("Case %d: %d\n", cs, (m + 1)>>1); } return 0; }
void findBridge(int u, int par) { int i, v; used[u] = 1; vis[u] = low[u] = ++dfsTime; for(i = fin[u]; i >= 0; i = next[i]) { v = to[i]; if(v == par) continue; if(used[v]) low[u] = min(low[u], vis[v]); else { findBridge(v, u); low[u] = min(low[u], low[v]); if(low[v] > vis[u]) bridge[i] = bridge[i^1] = 1; } } }