3132: 自启动
数字逻辑这一门课其实是比较有意思的。简单的零件巧妙的组合在一起,可以作出千变万化功能强大的东西,就像C语言,虽然只有顺序,选择,循环这三种结构而已,但把它们组合在一起可写出几乎所有任何实际当中的问题的程序。信吗?
不废话,俺从不罗嗦。什么是自启动?从任何一点开始,最后会在一个环内,就说明是可以自启动的,否则则不是。这个环结点数目要大于等于2。
一个自启动的例子:
无论从哪个字母开始最后都会进入E,F,G,H这个循环内,所以上面例子是可以自启动的。
输入
有多组测试数据,以文件结束。
第一行输入整数n,3=<n<=26。代表结点个数。每个结点用大写字母标记,并且按A-Z顺序依次标记。
第二行输入m,0=<m<=n*2 m表示行数。每行表示两个结点之间的关系。
例子:
4
2
A B
C D
表示A可以到B,但是B不能到A。其他没有说明的都默认为没有连接。注意:不会有自身结点到自身结点的数据。例如:A A。
输出
如果可以自启动输出YES,否则输出NO。
样例输入
8
8
A H
B G
G H
F G
E F
H E
C E
D E
4
3
B D
D C
C B
4
5
A B
B A
C A
D C
C D
4
4
A B
B A
C D
D C
样例输出
YES
NO
YES
YES
我最不喜欢的深搜,现在做出来了好像有点喜欢了 我好厉害(可是我好困啊
思路:
从每个点出发,进行深搜,一条路下去,搜过的点标记为1 如果走到之前已经被标记为1的点说明有环
不过从一个点可能去到不同的点,一个点一个点来 一条路走不通走另一条路的时候记得回来把之前标记为1的点标记为0(就是代码第16行
#include<bits/stdc++.h> using namespace std; int yy[101][101],vis[101],f; int maxx=0; void ydw(int n) { if(f==0)return;//you huan for(int i=65;i<=maxx;i++) { if(i==n)continue; if(yy[n][i]==1) { if(vis[i]==1){f=0;return ;}//you huan vis[i]=1;//如果没访问过的话 标记访问过 ydw(i);//并且递归与这个点相连的点 vis[i]=0;//如果之前走的路无环的话 要重新标记为没走过这个点 } } } int main() { int i,j,n,m; while(cin>>n) { cin>>m; maxx=0; memset(yy,0,sizeof(yy)); memset(vis,0,sizeof(vis)); getchar(); char a,b; for(i=0;i<m;i++) { scanf("%c %c",&a,&b); if(a>maxx)maxx=a;//找最大的字母 if(b>maxx)maxx=b; getchar(); yy[a][b]=1;//有边相连 } int yyy=0; for(i=65;i<=maxx;i++) { f=1; memset(flag,0,sizeof(vis));//每个字母进行深搜都要初始化 ydw(i); if(f==1)yyy=1;//wu huan } if(yyy==0)cout<<"YES\n"; else cout<<"NO\n"; } return 0; }