zoukankan      html  css  js  c++  java
  • 杭电 1269 连通图模板

    //自己理解着又敲了一遍代码,发现就是那回事,我希望自己能写写题解,一方便自己看,二方便别人理解
    //但诚挚地说,我现在还不明白连通图,只是跟着学长思路走了一遍,至于如果我自己第一次看到这个题,我是不会想到连通图的
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<stdio.h>
    #include<vector>//头文件,之后用来申请数组,这一点可能我理解的不清楚,只会比葫芦画瓢
    using namespace std;
    #define min(a, b) a<b?a:b
    #define N 10010
    vector<vector<int> >G;//学长说这个比下面那一行的方式好,可我也不知道为什么
    //vector<int>G[N];
    int n, m;
    int visit[N], rode[N];//visit用来表示访问的第几个数,rode用来存最短的距离
    int Stack[N];//自己建立栈
    bool Instack[N];// 判断是否在栈里面
    int Time, top;
    int num, cnt;//强连通图:(大家可以百度)是有向图,且对于图中任意两个不同的顶点i和j,都存在从i到j的路径,则称是强连通图;强连通图只有一个强连通分量。
    //故若判断小希是否都能到达所有房间,就是判断这个图是不是强连通图。也就是判断cnt是否等于1,且cnt=1时num是否等于n;cnt==1&&num==n代表图有一个连通分量且是他自身。即这是强连通图;
    //若不是强连通图,这道题是有向图,则称为“非强连通的有向图” 而它的连通分量可能有若干个
    void Init()//初始化,在需要很多处是滑的时候最好写在一个专有的函数里,方便检查Init  initially(初始化)
    {
        G.clear();//清空
        G.resize(n+1);//申请内存 //忘记申请内存了(这是我自己打的时候出现的错误)
        memset(visit, 0, sizeof(visit));
        memset(rode, 0, sizeof(rode));
        memset(Stack, 0, sizeof(Stack));
        memset(Instack, false, sizeof(Instack));
        num=cnt=Time=top=0;
    }
    void Tarjan(int u)
    {
        visit[u]=rode[u]=++Time;//visit和rode从1开始
        Stack[top++]=u;//入栈
        Instack[u]=true;//表明在栈里面了
        int len=G[u].size();//看有多少在那个里面 //这里写错了(这是我自己打的时候出现的错误)
        int v;
        for(int i=0; i<len; i++)
        {
            v=G[u][i];// 数组里面的第几个 //看来对那个不熟悉(这是我自己打的时候出现的错误)
            if(!visit[v])//其实也可以这样写if(!rode[v]),无非就是判断这个点是否访问过,没有访问过时visit[v] rode[v]都为0;
            {
                Tarjan(v);//递归,这种算法叫做Tarjan,你们可以上网搜搜加深理解
                rode[u]=min(rode[u], rode[v]);//当回朔时,就更改u也就是父亲的最短路径,因为儿子v的是最先更新的;
                //原因如下:因为递归到最后如果有“连通块”就会执行 else if 例如1->2->3->1;当执行到3->1时就会因为1已经在栈里面,而执行else if
                
            }
            else if(Instack[v])
            {
                rode[u]=min(rode[u], visit[v]);//其实写成rode[u]=min(rode[u], rode[v]);也是可以的,学长说当求割点时必须这样写;
            }
        }
        if(rode[u]==visit[u])
        {
            do
            {
                num++;
                v=Stack[--top];
                Instack[v]=false;
            }while(u!=v);//do while 会更简单吧,第一次用 do while
            cnt++;
        }
    }
    void solve()
    {
        Tarjan(1);
        if(cnt==1&&num==n)
            puts("Yes");
        else
            puts("No");
    }
    int main()
    {
        while(scanf("%d%d", &n, &m), n+m)
        {
            Init();
            int a, b;
            while(m--)
            {
                scanf("%d%d", &a, &b);
                G[a].push_back(b);
            }
            solve();
        }
        return 0;
    }
  • 相关阅读:
    php连接sql server的五种方法小结
    php链接sql server报错Fatal error: Call to undefined function mssql_connect()
    localStorage使用总结
    Java中获取完整的url
    wex5中需要使用到js相关资源的时候才去require
    javascript中,单引号是转义字符,就是让编辑器认为他后面的东西就是这个意思。
    wex5中win8或者win10操作系统studio中新建.w向导或其他的编辑窗口显示不全
    JavaScript isNaN() 函数
    sql语句,怎么取查询结果的位置
    Data组件的JSON数据格式
  • 原文地址:https://www.cnblogs.com/wazqWAZQ1/p/4705075.html
Copyright © 2011-2022 走看看