分析:先用BFS或者bellman-ford求ET点到所有点的最短路径长度,然后穷举所有点假设被删除后,DFS一下看能否与ET点连通。
Code
#include <iostream>
#include <sstream>
#include <stack>
using namespace std;
#define MAXN 100
bool g[MAXN][MAXN];
int dist[MAXN],n;
bool visited[MAXN];
void Bellman_ford(int s)
{
int i,j,k;
for(i=0;i<n;++i)
dist[i] = 100000;
dist[s] = 0;
for(k=1;k<n;++k)
for(i=0;i<n;++i)
for(j=0;j<n;++j)
if(g[j][i] && dist[j]>dist[i]+g[j][i])
dist[j] = dist[i] + g[j][i];
}
bool DFS(int source,int target)
{
if(source == target)
return true;
for(int i=0;i<n;++i)
if(g[source][i] && !visited[i])
{
visited[i] = true;
if(DFS(i,target))
return true;
visited[i] = false;
}
return false;
}
int main()
{
int t;
for(cin>>t;t!=0;--t)
{
int source;
cin>>n>>source>>ws;
memset(g,0,sizeof(g));
memset(dist,-1,sizeof(dist));
while(1)
{
string line;
getline(cin,line);
if(line == "" || cin.fail())
break;
istringstream iss;
iss.str(line);
int a,b;
iss>>a>>b;
g[a][b] = 1;
}
Bellman_ford(source);
int mindist = 1000000,opt = -1;
for(int i=1;i<n;++i)
{
if(i==source)
continue;
for(int j=0;j<n;++j)
visited[j] = false;
visited[i] = true;
visited[0] = true;
if(!DFS(0,source) && dist[i] < mindist)
{
mindist = dist[i];
opt = i;
}
}
if(opt == -1)
opt = 0;
cout<<"Put guards in room "<<opt<<"."<<endl;
if(t!=1)
cout<<endl;
}
return 0;
}