首页 > 代码库 > POJ 1130(一道纯水,bfs+dfs)

POJ 1130(一道纯水,bfs+dfs)

POJ 1130 


大概题意:给出一副图,求从起点到终点 (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;
}