广搜,深搜,单源最短路径,POJ(1130),ZOJ(1085)

题目链接:

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=85

http://poj.org/problem?id=1130

这两个题只有输入输出形式不一样。ZOJ的麻烦一点,这里用的ZOJ的输入输出方式

解题报告:

1、输入方式sscanf(line,"%d%d",&a,&b);表示在文本line中提取两个整形数据到a,b中

2、从外星人的角度来看,就是搜索单源最短路径,采用的方式是广搜。

3、删除某个点,从入口进入(0号房间),查看是否可以走到外星人的位置,采用深搜。

4、在删除哪一个点时,用枚举即可。

#include <stdio.h>
#include <string.h>
#include <queue>

using namespace std;

#define INF 0x3f3f3f3f
#define MAXN 105

int n,et;///n个房间,外星人所在的房间
bool data[MAXN][MAXN];   ///图的邻接矩阵
int dis[MAXN];           ///各点到外星人的房间的最短路径长度
int used[MAXN];


///广度优先搜索,站在外星人的角度看,就是单源最短路径问题
///搜索各个房间到外星人最短距离
void bfs_path()
{
    memset(dis,INF,sizeof(dis));
    dis[et]=0;

    queue <int>q;
    q.push(et);

    int x;
    while(!q.empty())
    {
        x=q.front();    ///取队列头结点
        q.pop();
        for(int i=0;i<n;i++)
        {
            ///经过房间x到外星人比从房间i到ET更近
            if(data[i][x]&&dis[x]+1<dis[i])
            {
                q.push(i);
                dis[i]=dis[x]+1;
            }
        }
    }
}


///去掉房间i,从房间0出发,判断能否到达外星人房间
///深度优先搜索
///形参id是当前正在搜索的房间编号
int dfs_search(int id)
{
    ///成功到达外星人房间
    if(id==et) return 1;

    ///房间id已经搜索
    used[id]=1;

    ///搜索下一个出口
    for(int i=0;i<n;i++)
    {
        if(!used[i]&&data[id][i])
        {
            if(dfs_search(i)) return 1;
        }
    }

    return 0;
}

int main()
{
    int T,iCase;
    char line[10];
    int a,b;///源房间,目标房间
    scanf("%d",&T);
    for(iCase=0;iCase<T;iCase++)
    {
        scanf("%d%d
",&n,&et);
        memset(data,false,sizeof(data));

        ///读取数据
        while(gets(line))
        {
            if(strcmp(line,"")==0)
                break;
            sscanf(line,"%d%d",&a,&b);
            data[a][b]=true;
        }

        bfs_path();

        ///枚举搜索最优解
        int d=dis[0];

        int room=0;

        for(int i=1;i<n;i++)
        {
            if(i==et) continue;

            memset(used,0,sizeof(used));
            ///设置在房间i,也就是说在图中将房间i拿掉
            used[i]=1;

            if(!dfs_search(0)&&dis[i]<d)
            {
                room=i;
                d=dis[i];
            }
        }

        if(iCase)    printf("
");
        printf("Put guards in room %d.
",room);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/TreeDream/p/5338672.html