题目链接:
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; }