Street Race[USACO]
第一问,判断各节点被删除之后,是否可以从起点到终点,如不可以,则满足要求。
第二问在第一问基础上,我用的bfs,判断是否成功:将图从当前节点分割成两部分(如果只分成了一部分,则为失败),是否所有边都为内部边,若是则当前节点满足。
/* ID: zhangyc1 LANG: C++ TASK: race3 */ #include <fstream> #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <queue> using namespace std; ofstream fileout("race3.out"); int N = 0; int arrLink[50][50], arrSize[50]; int nIndexMoved = -1; bool arrVisited[50], arrIsRightPart[50]; void prepairData() { memset(arrLink, 0, sizeof(arrLink)); memset(arrSize, 0, sizeof(arrSize)); ifstream filein("race3.in"); int nNum; while (filein >> nNum && nNum != -1) { while (nNum != -2) { arrLink[N][arrSize[N]] = nNum; filein >> nNum; arrSize[N]++; } N++; } filein.close(); } bool dfs(int nIndex) { if (nIndex == N - 1) { return true; } arrVisited[nIndex] = true; for (int i = 0; i < arrSize[nIndex]; i++) { if (!arrVisited[arrLink[nIndex][i]] && arrLink[nIndex][i] != nIndexMoved) { if(dfs(arrLink[nIndex][i])) return true; } } return false; } bool Partition(int nIndex) { memset(arrIsRightPart, 0, sizeof(arrIsRightPart)); queue<int> q; q.push(nIndex); int nRight = 0; while (!q.empty()) { int nTemp = q.front(); q.pop(); arrIsRightPart[nTemp] = true; nRight++; for (int i = 0; i < arrSize[nTemp]; i++) { if(!arrIsRightPart[arrLink[nTemp][i]]) q.push(arrLink[nTemp][i]); } } // 判断图是否只划分出了一部分 if (nRight == N || nRight == 1) return false; for (int i = 0; i < N; i++) { if (i == nIndex) continue; for (int j = 0; j < arrSize[i]; j++) { if (arrLink[i][j] == nIndex) continue; if (arrIsRightPart[i] ^ arrIsRightPart[arrLink[i][j]]) { return false; } } } return true; } void process() { int nCount = 0, arrCross[50]; for (int i = 1; i < N -1; i++) { nIndexMoved = i; memset(arrVisited, 0, sizeof(arrVisited)); if (!dfs(0)) { arrCross[nCount++] = i; } } int nCount2 = 0, arrCross2[50]; for (int i = 0; i < nCount; i++) { if (Partition(arrCross[i])) { arrCross2[nCount2++] = arrCross[i]; } } fileout << nCount; for (int i = 0; i < nCount; i++) { fileout << " " << arrCross[i]; } fileout << endl; fileout << nCount2; for (int i = 0; i < nCount2; i++) { fileout << " " << arrCross2[i]; } fileout << endl; } int main(){ prepairData(); process(); fileout.close(); return 0; }