zoukankan      html  css  js  c++  java
  • HIT暑期集训 tarjan,dfs序

    贴一个网上讲tarjan的博客

    https://blog.csdn.net/qq_34374664/article/details/77488976

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    #define maxn 105
    #define maxm 1005
    using namespace std;
    stack<int>st;
    int num,last[maxn],dfn[maxn],low[maxn],vis[maxn],cnt;
    struct edge
    {
        int to,nxt;
    }e[maxm<<1];
    void add(int x,int y)
    {
        e[++num].to=y;
        e[num].nxt=last[x];
        last[x]=num;
    }
    void tarjan(int x)
    {
        int i,y,tp;
        dfn[x]=low[x]=++cnt;
        st.push(x);
        vis[x]=1;
        for (i=last[x];i;i=e[i].nxt)
        {
            y=e[i].to;
            if (!dfn[y])
            {
                tarjan(y);
                low[x]=min(low[x],low[y]);
            }
            else if (vis[y])
            {
                low[x]=min(low[x],dfn[y]);
            }
        }
        if (low[x]==dfn[x])
        {
            while (!st.empty())
            {
                tp=st.top();
                printf("%d ",tp);
                vis[tp]=0;
                st.pop();
                if (tp==x) break;
            }
            printf("
    ");
        }
    }
    int main()
    {
        int i,n,m,x,y;
        scanf("%d%d",&n,&m);
        for(i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
        }
        for(i=1;i<=n;i++)
            if(!dfn[i])  tarjan(i);
        return 0;
    }
    tarjan求强连通分量模板

    B    CodeForces 723F

    题意:给一个联通的无向图,要求从中删边让它变为连通的树,并且s节点的度不超过ds,t节点的度不超过st。

    思路:将s与t从图中分离,求剩下图中的连通块,可知每个连通块只存在三种情况,①与s连边,②与t连边,③与s和t均连边。

    对于只与s或t相连的连通块,直接连边即可。

    对于与s和t均相连的连通块,若s与t不连通,则将连通块与s、t各连一条边;若s与t已经连通,则选择s、t中度数未超过要求的点连边(只连一条边)。

    若不存在与s和t均联通的连通块,则在s与t之间连边(因为是连通图,必定有边)。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 200005
    #define maxm 400005
    using namespace std;
    int num,to[maxm<<1],nxt[maxm<<1],last[maxn];
    int vis[maxn],cnt,vs[maxn],vt[maxn],s,t,tot;
    struct node
    {
        int x,y;
    }ans[maxn];
    void add(int x,int y)
    {
        to[++num]=y;nxt[num]=last[x];last[x]=num;
    }
    void dfs(int u)
    {
        int i,v;
        vis[u]=1;
        for (i=last[u];i;i=nxt[i])
        {
            v=to[i];
            if (v==s) vs[cnt]=u;
            if (v==t) vt[cnt]=u;
            if (!vis[v]) 
            {
                ans[++tot].x=u;ans[tot].y=v;
                dfs(v);
            }
         }
    }
    int main()
    {
        int i,j,x,y,n,m,ds,dt,flag=0,both=0;
        scanf("%d%d",&n,&m);
        for (i=1;i<=m;i++) 
        {
            scanf("%d%d",&x,&y);
            add(x,y);add(y,x);
        }
        scanf("%d%d%d%d",&s,&t,&ds,&dt);
        vis[s]=1;vis[t]=1; 
        for (i=1;i<=n;i++)
            if (!vis[i]) 
            {
                cnt++;
                dfs(i);    
            }
        for (i=1;i<=cnt;i++)
        {
            if (vs[i] && !vt[i])
            {
                ans[++tot].x=vs[i];ans[tot].y=s;
                ds--;
            }
            else if (!vs[i] && vt[i])
            {
                ans[++tot].x=vt[i];ans[tot].y=t;
                dt--;
            }
            else if (!vs[i] && !vt[i]) flag=1;
            else both++;
        }
        if (flag || dt<=0 || ds<=0 || both+1>ds+dt)
        {
            printf("No
    ");
            return 0;
        }
        if (!both)
        {
            ans[++tot].x=s;ans[tot].y=t;
        }
        else 
        {
            flag=0;
            for (i=1;i<=cnt;i++)
                if (vs[i] && vt[i])
                {
                    if (!flag)
                    {
                        ans[++tot].x=vs[i];ans[tot].y=s;
                        ans[++tot].x=vt[i];ans[tot].y=t;
                        flag=1;
                        ds--;dt--;
                    }
                    else 
                    {
                        if (ds)
                        {
                            ans[++tot].x=vs[i];ans[tot].y=s;
                            ds--;
                        }
                        else 
                        {
                            ans[++tot].x=vt[i];ans[tot].y=t;
                            dt--;
                        }
                    }
                }
        }
        printf("Yes
    ");
        for (i=1;i<=tot;i++) printf("%d %d
    ",ans[i].x,ans[i].y);
        return 0;
     } 
    View Code

    D    CodeForces 570D

    E    CodeForces 652E

    G    ZOJ 4097

    H    CodeForces 383C

    I    UVA 1108

  • 相关阅读:
    如何刷博客园阅读量
    反反爬虫策略
    [爬虫]抓取知乎百万用户信息之总结篇
    [爬虫]抓取知乎百万用户信息之爬虫模块
    [爬虫]抓取知乎百万用户信息之Redis篇
    [爬虫]抓取知乎百万用户信息之自建代理池
    [爬虫]抓取百万知乎用户信息之HttpHelper的迭代
    [爬虫]抓取百万知乎用户设计之实体设计
    [爬虫]抓取百万知乎用户数据之爬取思路
    [深度学习]实现一个博弈型的AI,从五子棋开始(2)
  • 原文地址:https://www.cnblogs.com/lsykk/p/13489961.html
Copyright © 2011-2022 走看看