zoukankan      html  css  js  c++  java
  • UVA11504 Dominos(有向图的强连通分量)

    这题就是用有向图的强连通分量来写,然后缩点,再找出入度为0的点的个数,就是答案

    注意:不知道为啥要动态分配内存...不这样就RE....郁闷

    // File Name: 11504.cpp
    // Author: Zlbing
    // Created Time: 2013/3/29 14:00:14
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    #include<cmath>
    #include<queue>
    using namespace std;
    #define CL(x,v); memset(x,v,sizeof(x));
    #define INF 0x3f3f3f3f
    #define LL long long
    #define REP(i,r,n) for(int i=r;i<=n;i++)
    #define RREP(i,n,r) for(int i=n;i>=r;i--)
    const int MAXN=1e5+10;
    //vector<int> G[MAXN];
    struct node{
        int u,v,next;
    }*Edge;
    int head[MAXN];
    int n,m;
    int lowlink[MAXN],sccno[MAXN],pre[MAXN];
    int scc_cnt,dfs_clock;
    stack<int> S;
    int k;
    void add(int u,int v){
        Edge[k].u = u;
        Edge[k].v = v;
        Edge[k].next = head[u];
        head[u] = k++;
    }
    
    void dfs(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        S.push(u);
        for(int i=head[u];i!=-1;i=Edge[i].next)
        {
            int v=Edge[i].v;
            if(!pre[v])
            {
                dfs(v);
                lowlink[u]=min(lowlink[u],lowlink[v]);
            }else if(!sccno[v])
            {
                lowlink[u]=min(lowlink[u],pre[v]);
            }
        }
        if(lowlink[u]==pre[u])
        {
            scc_cnt++;
            for(;;){
            int t=S.top();S.pop();
            sccno[t]=scc_cnt;
            if(t==u)break;
            }
        }
    }
    void find_scc(){
        memset(sccno,0,sizeof(sccno));
        memset(lowlink,0,sizeof(lowlink));
        memset(pre,0,sizeof(pre));
        dfs_clock=0,scc_cnt=0;
        for(int i=1;i<=n;i++)
            if(!pre[i])dfs(i);
    }
    int in[MAXN];
    
    int main()
    {
        int cas;
        scanf("%d",&cas);
        while(cas--)
        {
            scanf("%d%d",&n,&m);
            //CL(G,0);
            CL(head,-1);
            k=0;
            Edge=new node[m+5];
            REP(i,1,m)
            {
                int a,b;
                scanf("%d%d",&a,&b);
            //    G[a].push_back(b);
                add(a,b);
            }
            find_scc();
            CL(in,0);
    //        REP(i,1,n)
    //        {
    //            for(int j=0;j<G[i].size();j++)
    //            {
    //                int v=G[i][j];
    //                if(sccno[i]!=sccno[v])
    //                {
    //                    in[sccno[v]]++;
    //                }
    //            }
    //        }
            for(int i=0;i<k;i++)
            {
                int s=sccno[Edge[i].u];
                int e=sccno[Edge[i].v];
                if(s!=e)
                    in[e]++;
            }
            int ans=0;
            REP(i,1,scc_cnt)
                if(!in[i])ans++;
            printf("%d\n",ans);
        }
        return 0;
    }
  • 相关阅读:
    使用GetDIBts/SetDIBits高速逐点处理 from http://blog.sina.com.cn/s/blog_552ad2090100e3eu.html
    进程、应用程序域、程序集、对象上下文(转载)
    C# Data Structures
    **面试题
    你真的理解正确String某些特性了吗?
    Import data from files to SQL Server(用BULK INSERT命令导入数据详解)
    大战**面试
    海量数据面试题整理
    选择集合类
    电话面试题
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2989014.html
Copyright © 2011-2022 走看看