/* Name:1130Alien Security Author:Unimen Date: 20/04/11 18:51 */ /* 解题报告: 1、先找到各点到et房间的最短路径,然后枚举各个房间(设为守卫的房间),如果去这个枚举的房间, 到不了et,同时这时的路径为最短的即满足的了题意 2、SPFA算法求最短路径 */ #include <iostream> #include <cstring> #include <queue> #include <cstdio> using namespace std; const int MAXN = 300; int n,et; //房间个数,et房间编号 int g[MAXN][MAXN];//存储图的邻接矩阵 int distan[MAXN]; //SPFA求最短路径 void BfsShort() { queue<int> que; int x; distan[et] = 0; que.push(et); while(!que.empty()) { x = que.front(); que.pop(); for(int i=0; i<n; ++i) { //如果经过x到et比从房间i到et更近 //注意这里是逆向的 if(g[i][x] && distan[x] + 1 < distan[i]) { que.push(i); distan[i] = distan[x] + 1; } } } } //求从房间号为id的出发是否能走到et房间 int used[MAXN]; bool dfs(int nId) { if(nId == et) return true; used[nId] = 1; //搜索下一节点 for(int i=0; i<n; i++) { if(!used[i] && g[nId][i]) if(dfs(i)) return 1; } return 0; } int main() { char szInput[10]; while(cin>>n>>et) { memset(g, 0, sizeof(g)); //构造邻接矩阵 cin.get(); while(cin.getline(szInput,9)) { if(strcmp(szInput, "") == 0) break; int a,b; sscanf(szInput, "%d %d",&a,&b); g[a][b] = 1; } //初始化distance for(int i=0; i<MAXN; ++i) distan[i] = 0xffff; //寻找各个房间到et的最短路径 BfsShort(); int d =distan[0]; int room = 0; //守卫的房间 for(int i=1; i<n; i++) { if(i == et) continue; memset(used, 0, sizeof(used)); used[i] = 1; if(!dfs(0) && distan[i] < d) { d = distan[i]; room = i; } } cout<<"Put guards in room "<<room<<"."<<endl; } }