第一问,判断各节点被删除之后,是否可以从起点到终点,如不可以,则满足要求。
第二问在第一问基础上,我用的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;
}