zoukankan      html  css  js  c++  java
  • P1536 村村通

    传送门

    本题的标算是并查集查找连通块的个数,为了练习下Tarjan,就用Tranjan写一波;

    思路:tarjan

    观察题目,市政府“村村通工程”的目标是使全市任何两个城镇间都可以实现交通,表明图为多个联通块,因为是无向边,所以每个联通块一定是一个强连通分量(显然)。

    那么问题就变成了 查找联通块,将所有联通块联通,显然需要n-1条边。

    所以 只需要tarjan搜索强连通分量的个数,然后输出强连通分量个数减一即为答案。

    代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXN=100005;
    int n,m;
    vector<int> G[MAXN];//试一下动态存图
    int dfn[MAXN],low[MAXN],cnt=0,index_=0;
    int scc[MAXN],size[MAXN];
    bool inStack[MAXN];
    stack<int> st;
    void tarjan(int u)
    {
        index_++;
        dfn[u]=index_;
        low[u]=index_;
        st.push(u);
        inStack[u]=true;
        for(int i=0;i<G[u].size();i++)
        {
            if(!dfn[G[u][i]])
            {
                tarjan(G[u][i]);
                low[u]=min(low[u],low[G[u][i]]);
            }
            else if(inStack[G[u][i]])
                low[u]=min(low[u],dfn[G[u][i]]);
        }
        if(low[u]==dfn[u])
        {
            cnt++;
            while(st.top()!=u)
            {
                scc[st.top()]=cnt;
                size[cnt]++;
                inStack[st.top()]=false;
                st.pop();
            }
            scc[st.top()]=cnt;
            size[cnt]++;
            inStack[st.top()]=false;
            st.pop();
        }
    }
    inline void clear()
    {
        for(int i=0;i<=MAXN;i++)
        G[i].clear();
        cnt=0;
        memset(scc,0,sizeof(scc));
        memset(inStack,0,sizeof(inStack));
        memset(size,0,sizeof(size));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        while( !st.empty() )
          st.pop();
        index_=0;
    }
    int main()
    {
        ios::sync_with_stdio(0);   //syn加速
        for(;;)
        {
            clear();
            cin>>n;
            if(n==0) break;
            cin>>m;
            for(int i=0;i<m;i++)
               {
                int x,y;
                cin>>x>>y;
                G[x].push_back(y);
                G[y].push_back(x);
            }
            for(int i=1;i<=n;i++)
                if(!dfn[i])
                    tarjan(i);
            cout<<cnt-1<<endl;        
        }
    return 0;
    } 
  • 相关阅读:
    jsp页面间传递参数 中文乱码问题(zz)
    java 生成xml
    java dom4j 解析xml
    生成不重复的32为随机码
    [HYSBZ
    七夕祭
    [CF741D] Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
    Baltic2014 sequence
    [洛谷P2459] SDOI2011 消耗战
    [洛谷P4172] WC2006 水管局长
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9571556.html
Copyright © 2011-2022 走看看