zoukankan      html  css  js  c++  java
  • 洛谷 P2746 [USACO5.3]校园网 Network of Schools 题解

    Tarjan 模板题

    第一问就是缩点之后看有多少个入度为零的点就好了。

    第二问是在缩点后将每个点的入度和出度都求出(只要有入度或出度就置为1),然后比较哪个有值的多,将多的作为答案输出。原因是由题可得,要使缩完的点也构成一个强连通分

    量,即入度和出度都大于等于1。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define maxn 10010
      6 using namespace std;
      7 inline int read() 
      8 {
      9     int x=0;
     10     bool f=1;
     11     char c=getchar();
     12     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
     13     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
     14     if(f) return x;
     15     return 0-x;
     16 }
     17 inline void write(int x)
     18 {
     19     if(x<0){putchar('-');x=-x;}
     20     if(x>9)write(x/10);
     21     putchar(x%10+'0');
     22 }
     23 struct node
     24 {
     25     int v,nex;
     26 }edge[maxn];
     27 int n,cnt,inl,top,res1,res2,num,cd2,rd2;
     28 int head[maxn],st[maxn],low[maxn],dfn[maxn],inn[maxn],si[maxn],rd[maxn],cd[maxn];
     29 inline void add(int x,int y)
     30 {
     31     cnt++;
     32     edge[cnt].v=y;
     33     edge[cnt].nex=head[x];
     34     head[x]=cnt;
     35 }
     36 inline void Tarjan(int from) 
     37 {
     38     dfn[from]=low[from]=++num;
     39     st[++top]=from;
     40     for(int i=head[from];i!=-1;i=edge[i].nex)
     41     {
     42         int to=edge[i].v;
     43         if(!dfn[to])
     44         {
     45             Tarjan(to);
     46             low[from]=min(low[from],low[to]);
     47         }
     48         else if(!inn[to])
     49             low[from]=min(low[from],dfn[to]);
     50     }
     51     if(low[from]==dfn[from])
     52     {
     53         inn[from]=++inl;
     54         ++si[inl]; 
     55         while(st[top]!=from)
     56         {
     57             ++si[inl];
     58             inn[st[top]]=inl;
     59             --top;
     60         }
     61         --top;
     62     }
     63 }
     64 int main()
     65 {
     66     memset(head,-1,sizeof(head));
     67     n=read();
     68     for(int i=1;i<=n;i++)
     69     {
     70         int x;
     71         while(1)
     72         {
     73             x=read();
     74             if(x!=0)add(i,x);
     75             else break;
     76         }
     77     }
     78     for(int i=1;i<=n;i++)
     79         if(!dfn[i])
     80             Tarjan(i);
     81     for(int i=1;i<=n;i++)
     82        for(int j=head[i];j!=-1;j=edge[j].nex)
     83        {
     84             if(inn[i]!=inn[edge[j].v])
     85             {
     86                 rd[inn[edge[j].v]]++;
     87                 cd[inn[i]]++;
     88             }
     89 
     90        }
     91     if(inl==1)
     92     {
     93         cout<<1<<endl<<0;
     94         return 0;
     95     }
     96     for(int i=1;i<=inl;i++)
     97         if(rd[i]==0)
     98             res1++;
     99     write(res1);
    100     cout<<endl;
    101     for(int i=1;i<=inl;i++)
    102     {
    103         if(cd[i]==0)
    104             cd2++;
    105         if(rd[i]==0)
    106             rd2++;
    107     }
    108     res2=max(cd2,rd2);
    109     write(res2);
    110     return 0;
    111 }
    请各位大佬斧正(反正我不认识斧正是什么意思)
  • 相关阅读:
    断行
    椭圆曲线质因数分解2
    sqrti128
    HLPP
    Optimize Prime Sieve
    python 一些乱七八糟的东西
    移动机器人建图与导航代码实现——3.Path Tracking
    移动机器人建图与导航代码实现——2.Path Planning
    移动机器人建图与导航代码实现——1.Hector SLAM
    移动机器人建图与导航代码实现——0.目录
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11237783.html
Copyright © 2011-2022 走看看