標籤:
迷宮城堡Problem Description為了訓練小希的方向感,Gardon建立了一座大城堡,裡面有N個房間(N<=10000)和M條通道(M<=100000),每個通道都是單向的,就是說若稱某通道連通了A房間和B房間,只說明可以通過這個通道由A房間到達B房間,但並不說明通過它可以由B房間到達A房間。Gardon需要請你寫個程式確認一下是否任意兩個房間都是相互連通的,即:對於任意的i和j,至少存在一條路徑可以從房間i到房間j,也存在一條路徑可以從房間j到房間i。
Input輸入包含多組資料,輸入的第一行有兩個數:N和M,接下來的M行每行有兩個數a和b,表示了一條通道可以從A房間來到B房間。檔案最後以兩個0結束。 Output對於輸入的每組資料,如果任意兩個房間都是相互串連的,輸出"Yes",否則輸出"No"。 Sample Input3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0 Sample OutputYes
No Answer暴力DFS,從第一個房間開始搜:1->2->3,因為有環的存在,要判斷是否回到了起點,否則會無限迴圈。某個房間能走到某個房間用set來記錄,不會重複。
#include <set>#include <cmath>#include <queue>#include <vector>#include <cstdio>#include <string>#include <cstring>#include <iostream>#include <algorithm>#define ms(a) memset(a,0,sizeof(a))#define msp memset(mp,0,sizeof(mp))#define msv memset(vis,0,sizeof(vis))using namespace std;int n,m;bool vis[10001];set<int> s[10001];void dfs(int ori,int x){ set<int>::iterator it; vector<int> v; for(it=s[x].begin();it!=s[x].end();it++) v.push_back(*it); vector<int>::iterator itv; for(itv=v.begin();itv!=v.end();itv++) { if(vis[*itv])continue; //如果要搜尋的房間比起點房間編號小,說明那個房間已經搜尋過了 //這時,只要把那個房間的所有能走到的房間insert一遍就行了 /*//這個剪枝有問題 if(*itv<ori) { for(it=s[*itv].begin();it!=s[*itv].end();it++) { if(*it==ori)continue; s[ori].insert(*it); } continue; } */ s[ori].insert(*itv); vis[*itv]=1; dfs(ori,*itv); }}int main(){ while(cin>>n>>m&&(n||m)) { while(m--) { int a,b; cin>>a>>b; s[a].insert(b); } bool flag=1; for(int i=1; i<=n; i++) { if((int)s[i].size()==n-1)continue; msv; vis[i]=1; dfs(i,i); //剪枝,如果某個房間不能走到其他所有房間, //就沒有繼續搜尋的意義了 if((int)s[i].size()!=n-1) { flag=0; break; } } for(int i=1;i<=n&&flag;i++) { if((int)s[i].size()!=n-1) { flag=0; } } if(flag)printf("Yes\n"); else printf("No\n"); for(int i=1;i<=n;i++) s[i].clear(); } return 0;}View Code
HDU 1269 迷宮城堡(DFS)