zoukankan      html  css  js  c++  java
  • 【IOI 1996】 Network of Schools

    【题目链接】

             点击打开链接

    【算法】

              对于第一问,将这个图缩点,输出出度为零的点的个数

              对于第二问,同样将这个图缩点,输出入度为零、出度为零的点的个数的最大值

    【代码】

              

    #include <algorithm>
    #include <bitset>
    #include <cctype>
    #include <cerrno>
    #include <clocale>
    #include <cmath>
    #include <complex>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <deque>
    #include <exception>
    #include <fstream>
    #include <functional>
    #include <limits>
    #include <list>
    #include <map>
    #include <iomanip>
    #include <ios>
    #include <iosfwd>
    #include <iostream>
    #include <istream>
    #include <ostream>
    #include <queue>
    #include <set>
    #include <sstream>
    #include <stdexcept>
    #include <streambuf>
    #include <string>
    #include <utility>
    #include <vector>
    #include <cwchar>
    #include <cwctype>
    #include <stack>
    #include <limits.h>
    using namespace std;
    #define MAXN 10010
    
    struct Edge
    {
            int to,nxt;
    } e[MAXN];
    
    int i,x,n,tot,timer,top,cnt;
    int head[MAXN],dfn[MAXN],low[MAXN],stk[MAXN],belong[MAXN];
    bool instack[MAXN];
    
    template <typename T> inline void read(T &x)
    {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    template <typename T> inline void write(T x)
    {
        if (x < 0)
        {
            putchar('-');
            x = -x;
        }
        if (x > 9) write(x/10);
        putchar(x%10+'0');
    }
    template <typename T> inline void writeln(T x)
    {
        write(x);
        puts("");
    }
    inline void add(int u,int v)
    {
            tot++;
            e[tot] = (Edge){v,head[u]};
            head[u] = tot;            
    }
    inline void tarjan(int u)
    {
            int i,v;
            dfn[u] = low[u] = ++timer;
            instack[u] = true;
            stk[++top] = u;
            for (i = head[u]; i; i = e[i].nxt)
            {
                    v = e[i].to;        
                    if (!dfn[v])
                    {
                            tarjan(v);
                            low[u] = min(low[u],low[v]);    
                    }    else
                    {
                            if (instack[v])
                                    low[u] = min(low[u],dfn[v]);
                    }
            }
            if (dfn[u] == low[u])
            {
                    cnt++;
                    while (stk[top+1] != u)
                    {
                            instack[stk[top]] = false;
                            belong[stk[top]] = cnt;
                            top--;
                    }
            }
    }
    inline void solve()
    {
            int i,j,s1 = 0,s2 = 0;
            static int in[MAXN],out[MAXN];
            memset(in,0,sizeof(in));
            memset(out,0,sizeof(out));
            memset(dfn,0,sizeof(dfn));
            memset(low,0,sizeof(low));
            cnt = timer = 0;
            for (i = 1; i <= n; i++)
            {
                    if (!dfn[i])
                            tarjan(i);    
            }    
            for (i = 1; i <= n; i++)
            {
                    for (j = head[i]; j; j = e[j].nxt)
                    {
                            if (belong[i] != belong[e[j].to])
                            {
                                    in[belong[e[j].to]]++;
                                    out[belong[i]]++; 
                            }
                    }
            }
            for (i = 1; i <= cnt; i++)
            {
                    if (!in[i]) s1++;
                    if (!out[i]) s2++;
            }
            if (cnt == 1) printf("%d
    %d
    ",1,0);
            else printf("%d
    %d
    ",s1,max(s1,s2));
    }
    
    int main() {
            
            while (scanf("%d",&n) != EOF)
            {
                    tot = 0;
                    for (i = 1; i <= n; i++) head[i] = 0;
                    for (i = 1; i <= n; i++)
                    {
                            while (scanf("%d",&x) && x) add(i,x);    
                    }    
                    solve();
            }
            
            return 0;
        
    }
  • 相关阅读:
    http://www.jdon.com/jivejdon/thread/37340
    我的英语死在类似的问题上
    Linux之read命令使用
    SIP注册呼叫流程简介
    sh里的变量 $0 $1 $$ $#
    LTE 逻辑分层和接口协议
    LTE语音业务VOLTE
    shell编程——if语句 if z n f eq ne lt
    高通QXDM抓modem log
    LTE与VOLTE基础知识
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196323.html
Copyright © 2011-2022 走看看