大概题意:给出一副图,求从起点到终点 (0->ET) 必须经过的一点。
我的思路:首先DFS求出经过每点的次数,必过的一点的次数一定最高,但是就这样吗?有可能有多个必过的点,所以还要找出离ET最近的点,这里就利用BFS逐层搜索的性质求每点到ET的距离。
#include<iostream>
#include<cstdio>
#include<string.h>
#include<iomanip>
#include<queue>
#include<algorithm>
#define INF 0x3fffffff
using namespace std;
const int N=20;
int n,m;
int graph[N][N];
int vis[N];
int time[N];
int dis[N];
struct node{
int p;
int time;
int dis;
}condi[N];
int cmp(node a,node b)
{
if(a.time==b.time)
return a.dis<b.dis;
return a.time>b.time;
}
int dfs(int cur)
{
int ok=0;
if(cur==0)
{
condi[0].time++;
return 1;
}
for(int i=0;i<n;i++)
{
if(!vis[i]&&graph[cur][i])
{
vis[i]=1;
ok+=dfs(i);
vis[i]=0;
}
}
condi[cur].time+=ok;
return ok;
}
void bfs(int cur)
{
memset(vis,0,sizeof vis);
condi[cur].dis=0;
queue<int> q;
q.push(cur);
vis[cur]=1;
while(!q.empty())
{
int pos=q.front();
q.pop();
for(int i=0;i<n;i++)
{
if(graph[pos][i]&&!vis[i])
{
vis[i]=1;
condi[i].dis=condi[pos].dis+1;
q.push(i);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
int u,v;
memset(graph,0,sizeof graph);
memset(vis,0,sizeof vis);
for(int i=0;i<n;i++)
{
condi[i].dis=INF;
condi[i].time=0;
condi[i].p=i;
}
while(scanf("%d%d",&u,&v)!=EOF)
{
graph[v][u]=1;
}
vis[m]=1;
dfs(m);
bfs(m);
condi[m].dis=INF;
sort(condi,condi+n,cmp);
printf("Put guards in room %d.\n",condi[0].p);
return 0;
}