• hdu 1269


    题意:判断是否为强连通图

    解题思路:判断强连通分量是否为1 K算法

    zsd:

    1 对原图进行深度优先搜索 记录每个顶点的dfn值

    2 将图反向 得到逆图

    3 选择从当前dfn值最大的定点出发,对逆图进行dfs搜索,删除能遍历到得顶点 这些顶点构成一个强连通分量

    4如果还有顶点没有删除继续执行3步

    第一种解法;
    #include<iostream> using namespace std; struct G { int dest; G *next; }; int n,m; G *ga[10001]; G *gt[10001]; int path[10001]; int vis[10001]; void addedge(G *g[],int i,int j) { G *l=new G; l->dest=j; l->next=g[i]; g[i]=l; } void dfsa(int u) { G *l=ga[u]; if(!vis[u]) { vis[u]=1; for(l;l!=NULL;l=l->next) dfsa(l->dest); path[0]++; path[path[0]]=u; } } void dfst(int u) { G *l=gt[u]; if(!vis[u]) { vis[u]=1; for(l;l!=NULL;l=l->next) dfst(l->dest); } } void k() { int i; path[0]=0; memset(vis,0,sizeof(vis)); //搜索原图 for(i=1;i<=n;i++) { if(!vis[i]) dfsa(i); } memset(vis,0,sizeof(vis)); int sum=0; for(i=n;i>=1;i--) { if(!vis[path[i]]) { sum++; dfst(path[i]); } } if(sum>1) printf("No "); else printf("Yes "); } int main() { int a,b; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0) break; for(int i=1;i<=n;i++) ga[i]=gt[i]=NULL; while(m--) { scanf("%d%d",&a,&b); addedge(ga,a,b); addedge(gt,b,a); } k(); } return 0; }
    第二种解法:
    #include<stdio.h>
    #include<string.h>
    #include<vector>
    using namespace std;
    const int Max=11000;
    #define min(a,b) a>b?b:a
    int n,m,top,index;
    int instack[Max],stack[Max],loop[Max];
    int DFN[Max],LOW[Max],ans;
    vector<int> V[Max];
    void init()
    {
        top=ans=0;
        index=1;
        int i;
        for(i=0;i<Max;i++)
        {
            V[i].clear();
            loop[i]=0;
            instack[i]=0;
        }
    }
    void tarjan(int u)
    {
        int i,j,v;
        LOW[u]=DFN[u]=index++;
        stack[top++]=u;
        loop[u]=1;
        instack[u]=1;
        for(i=0;i<V[u].size();i++)//考虑所有与u相连的边
        {
            v=V[u][i];
            if(loop[v]==0)//如果v还没有访问过
            {
                tarjan(v);//dfs(v)
                LOW[u]= min(LOW[u],LOW[v]);
            }
           else if(instack[v])//否则是反向边
                LOW[u]= min(LOW[u],DFN[v]);//low[u]为u节点能追溯到得最早的节点编号
            
        }
        if(DFN[u]==LOW[u])//如果此节点的dfn[u]与low[u]相等 则说明以u为节点的搜索树上的所有节点是一个强连通分量
        {
            do{ //把所有的强连通节点出栈
                j=stack[top-1];
                instack[j]=0;
                top--;
            }while(j!=u);
            ans++;//强连通分量的个数
        }
    }
    int main()
    {
        int i,j,x,y;
        while(~scanf("%d%d",&n,&m)&&n+m)
        {
            init();
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&x,&y);
                V[x].push_back(y);
            }
            for(i=1;i<=n;i++)
                if(loop[i]==0)
                       tarjan(i);
            if(ans==1||n==1)
                printf("Yes ");
            else
                printf("No ");
        }
    }
  • 相关阅读:
    webstorm 取消拖动代码
    可读流
    页面上怎么使用svg
    从element-ui按需引入去探索
    vue组件库用markdown生成文档
    create-react-app中的babel配置探索
    svg 使用中的疑惑点
    express中是如何处理IP的?
    koa中是如何封装获取客户端IP的?
    博客园文章添加目录
  • 原文地址:https://www.cnblogs.com/zhangdashuai/p/3711814.html
Copyright © 2020-2023  润新知