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;
}
View Code

 

 

posted @ 2019-05-11 22:08  -第4题-  阅读(245)  评论(0编辑  收藏  举报