• [poj1236]Network of Schools(targin缩点SCC)


    题意:有N个学校,从每个学校都能从一个单向网络到另外一个学校。
    1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件。
    2:至少需要添加几条边,使任意向一个学校发放软件后,经过若干次传送,网络内所有的学校最终都能得到软件。

    解题关键:1、缩点之后求出入度为0的点的个数;

         2、缩点之后入度为0点和出度为0点的个数的max,(因为是任意点可到达全图),若存在点到达全图,添加入度-1条边即可。

    注意特判只有一个节点的情况。

    dfn需要初始化

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<cmath>
     6 #include<algorithm>
     7 using namespace std;
     8 typedef long long ll;
     9 #define MAXN 120
    10 #define MAXM 100010
    11 struct edge{
    12     int to,nxt;
    13 }e[MAXM];
    14 int degree1[MAXN],degree2[MAXN];
    15 int head[MAXN],st[MAXN],dfn[MAXN],lowest[MAXN],belong[MAXN];
    16 bool inst[MAXN];
    17 int n,scnt,top,tot;//scnt从1开始
    18 void init(){
    19     memset(head,-1,sizeof head);
    20     memset(degree1,0,sizeof degree1);
    21     memset(degree2,0,sizeof degree2);
    22     scnt=top=tot=0;
    23 }
    24 
    25 void add_edge(int u, int v){
    26     e[tot].to=v;
    27     e[tot].nxt=head[u];
    28     head[u]=tot++;
    29 }
    30 
    31 void Tarjan(int u){
    32     dfn[u]=lowest[u]=++tot;
    33     inst[u]=1;
    34     st[top++]=u;
    35     for(int i=head[u];i!=-1;i=e[i].nxt){
    36         int v=e[i].to;
    37         if(!dfn[v]){
    38             Tarjan(v);
    39             lowest[u]=min(lowest[u],lowest[v]);
    40         }
    41         else if(inst[v]){
    42             lowest[u]=min(lowest[u],dfn[v]);//也可用lowest
    43         }
    44     }
    45     if(dfn[u]==lowest[u]){
    46         scnt++;
    47         int t;
    48         do{
    49             t=st[--top];
    50             inst[t]=false;
    51             belong[t]=scnt;
    52         }while(t!=u);
    53     }
    54 }
    55 
    56 void solve(){//缩点
    57     for(int i=1;i<=n;i++)  if(!dfn[i])  Tarjan(i);
    58     for(int i=1;i<=n;i++){
    59         for(int j=head[i];j!=-1;j=e[j].nxt){
    60             if(belong[i]!=belong[e[j].to]){
    61                 degree1[belong[i]]++,degree2[belong[e[j].to]]++;
    62             }
    63         }
    64     }
    65     int sum1=0,sum2=0;
    66     for(int i=1;i<=scnt;i++){
    67         if(!degree1[i]) sum1++;
    68         if(!degree2[i]) sum2++;
    69     }
    70     if(scnt==1){//1个节点进行特判 
    71         printf("1
    0
    ");
    72         return;
    73     }
    74     printf("%d
    ",sum2);
    75     printf("%d
    ",max(sum1,sum2));
    76     return;
    77 }
    78 
    79 int main(){
    80     int a;
    81     while(scanf("%d",&n)!=EOF){
    82         init();
    83         int m=1;
    84         while(scanf("%d",&a)){
    85             if(a==0){
    86                 m++;
    87                 if(m>n) break;
    88                 continue;
    89             }
    90             add_edge(m,a);
    91         }
    92         solve();
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    【转载】loadrunner使用system()函数调用Tesseract-OCR识别验证码遇到的问题
    实现LoadRunner多个场景的顺序执行(命令行)
    BAT批处理(一)
    BAT批处理(二)
    BAT批处理(五)
    BAT批处理(六)
    BAT批处理(三)
    BAT批处理(四)
    DOS工具
    python3.0与2.x之间的区别
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7566287.html
Copyright © 2020-2023  润新知