http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5343
当时是一个学弟过的,真心没想出来,回想起来其实可能有点后悔做ACM了,确实智商不够......
11去牡丹江比赛,如果悲剧,ACM生涯就彻底悲剧了,尽量出结果......啥不说,专心刷题
此题还是参考了答案,,,
题目要求:按照次序访问某些点,如果能满足而且能遍历全图,输出yes否则no
学到:
1、是不是能按照规定次序,那么就这么看,按照规定次序,DFS第一个点,过程中如果遇到第二个点,加入Set,从第二个点开始搜,如果能遇到第三个点,加入Set,直到所有点都能遍历完。
最后检查图是不是被遍历一遍
2、检查图是不是联通的另一种方法:
DFS的过程中vis数组记录,最后扫一遍,看是不是都遍历过了
3、DFS写法注意,DFS到监控点马上停止,否则的话,就不能保证按照规定次序,哎,DFS功力不够没想到啊
//#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algorithm> #include <string> #include <iostream> #include <iomanip> #include <cmath> #include <map> #include <set> #include <queue> using namespace std; #define ls(rt) rt*2 #define rs(rt) rt*2+1 #define ll long long #define ull unsigned long long #define rep(i,s,e) for(int i=s;i<e;i++) #define repe(i,s,e) for(int i=s;i<=e;i++) #define CL(a,b) memset(a,b,sizeof(a)) #define IN(s) freopen(s,"r",stdin) #define OUT(s) freopen(s,"w",stdout) const ll ll_INF = ((ull)(-1))>>1; const double EPS = 1e-8; const double pi = acos(-1.0); const int INF = 100000000; const int MAXN = 100000+50; vector<int>g[MAXN*2];// set<int>s; int n,m,k,k2; int vis[MAXN],pos[MAXN],sm[MAXN]; void dfs(int u) { vis[u]=1; int si=g[u].size(); for(int i=0;i<si;i++) { int v=g[u][i]; if(!vis[v]) { //vis[v]=1; if(pos[v])s.insert(v); else dfs(v); // } } } void read() { CL(vis,0); CL(pos,0); s.clear(); scanf("%d%d%d",&n,&m,&k); for(int i=0;i<=n;i++)g[i].clear(); int u,v; for(int i=0; i<k; i++) scanf("%d",&u); for(int i=0;i<m;i++) { scanf("%d%d",&u,&v); g[u].push_back(v); g[v].push_back(u); } scanf("%d",&k2); for(int i=0;i<k2;i++) { scanf("%d",&sm[i]); pos[sm[i]]=1; } if(k2<k) { puts("No"); return; } dfs(sm[0]); for(int i=1;i<k2;i++) { if(s.find(sm[i]) == s.end()) { puts("No"); return; } else dfs(sm[i]); } for(int i=1;i<=n;i++) if(!vis[i]) { puts("No"); return; } puts("Yes"); } int main() { //IN("zoj3811.txt"); int ncase; scanf("%d",&ncase); while(ncase--) { read(); } return 0; }