zoukankan      html  css  js  c++  java
  • 轰炸---------------tarjan

    题目描述

    有 n 座城市,城市之间建立了 m 条有向的地下通道。你需要发起若干轮轰炸,每轮可以轰炸任意多个城市。但每次轰炸的城市中,不能存在两个不同的城市 i,j 满足可以通过地道从城市 i 到达城市 j。你需要求出最少需要多少轮可以对每座城市都进行至少一次轰炸。

    输入数据

    第一行两个整数 n,m。接下来 m 行每行两个整数 a,b 表示一条从 a 连向 b 的单向边。

    输出数据

    一行一个整数表示答案。

    样例输入

    5 4

    1 2

    2 3

    3 1

    4 5

    样例输出

    3

    数据范围

    对于 20%的数据,n,m≤10。

    对于 40%的数据,n,m≤1000。

    对于另外 30%的数据,保证无环。

    对于 100%的数据,n,m≤1000000。

    一句话题解:偏序集最小反链覆盖等于最长链。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n,m,x,y,ans;
     4 int cnt,top,sum;
     5 int dfn[1000050];
     6 int low[1000050];
     7 int col[1000050];
     8 int siz[1000050];
     9 int du[1000050];
    10 int t[1000050];
    11 int f[1000050];
    12 struct node
    13 {
    14     int tot;
    15     int head[1000050];
    16     int nex[1000050];
    17     int ver[1000050];
    18     void add(int x,int y)
    19     {
    20         nex[++tot]=head[x];
    21         ver[tot]=y;
    22         head[x]=tot;
    23     }
    24 }a,b;
    25 void tarjan(int u)
    26 {
    27     dfn[u]=low[u]=++cnt;
    28     t[++top]=u;
    29     for(int i=a.head[u];i;i=a.nex[i])
    30         if(!dfn[a.ver[i]])
    31         {
    32             tarjan(a.ver[i]);
    33             low[u]=min(low[u],low[a.ver[i]]);
    34         }
    35         else if(!col[a.ver[i]])
    36             low[u]=min(low[u],dfn[a.ver[i]]);
    37     if(dfn[u]==low[u])
    38     {
    39         ++sum;
    40         while(t[top+1]!=u)
    41         {
    42             col[t[top]]=sum;
    43             ++siz[sum];
    44             --top;
    45         }
    46     }
    47 }
    48 int main()
    49 {
    50     scanf("%d%d",&n,&m);
    51     for(int i=1;i<=m;++i)
    52     {
    53         scanf("%d%d",&x,&y);
    54         a.add(x,y);    
    55     }
    56     for(int i=1;i<=n;++i)
    57         if(!dfn[i])
    58             tarjan(i);
    59     for(int i=1;i<=n;++i)
    60         for(int j=a.head[i];j;j=a.nex[j])
    61             if(col[i]!=col[a.ver[j]])
    62             {
    63                 ++du[col[a.ver[j]]];
    64                 b.add(col[i],col[a.ver[j]]);
    65             }
    66     top=0;
    67     for(int i=1;i<=sum;++i)
    68         if(du[i]==0)
    69             t[++top]=i;
    70     while(top)
    71     {
    72         int now=t[top];
    73         f[now]+=siz[now];
    74         --top;    ans=max(ans,f[now]);
    75         for(int i=b.head[now];i;i=b.nex[i])
    76         {
    77             f[b.ver[i]]=max(f[b.ver[i]],f[now]);
    78             if(--du[b.ver[i]]==0)
    79                 t[++top]=b.ver[i];
    80         }
    81     }
    82     printf("%d",ans);
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    iOS 地图与定位开发系列教程(一)
    opencv 之 transformation
    the brain 8.0
    vs中添加库文件WinMM.Lib
    JAVA简单性能检测
    【转帖】一套鼠标控制2台电脑
    Synergy工具一套键盘鼠标连接多台机器
    文件夹下所有文件及子文件夹将文件名小写
    捕捉Facebook Like的数据
    按键精灵的网页自动化测试
  • 原文地址:https://www.cnblogs.com/wyher/p/10362233.html
Copyright © 2011-2022 走看看