10.28T5 tarjan+dfs

5162 -- 【11.04题目】轰炸

Description

  战狂也在玩《魔方王国》。他只会征兵而不会建城市,因此他决定对小奇的城市进行轰炸。
  小奇有n座城市,城市之间建立了m条有向的地下通道。战狂会发起若干轮轰炸,每轮可以轰炸任意多个城市。
  每座城市里都有战狂部署的间谍,在城市遭遇轰炸时,它们会通过地下通道撤离至其它城市。非常不幸的是,在地道里无法得知其它城市是否被轰炸,如果存在两个不同的城市i,j,它们在同一轮被轰炸,并且可以通过地道从城市i到达城市j,那么城市i的间谍可能因为撤离到城市j而被炸死。为了避免这一情况,战狂不会在同一轮轰炸城市i和城市j。注意:炸毁的城市还是能够到达的。
你需要求出战狂最少需要多少轮可以对每座城市都进行至少一次轰炸

Input

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

Output

  输出一行仅一个整数表示答案。

Sample Input

5 4 1 2 2 3 3 1 4 5

Sample Output

3

Hint

【数据范围】
  对于20%的数据,n,m<=10。
  对于40%的数据,n,m<=1000。
  对于另外30%的数据,保证无环。
  对于100%的数据,n,m<=1000000
 
 
 
 
tarjan先缩环,然后记录联通块的大小直接dfs,dfs的时候加上自己儿子的最大值就可以了
code:
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<queue> 
  4 #define N 1000005
  5 using namespace std;
  6 long long n,m;
  7 struct node{
  8     long long u,v;
  9 }e[N],e1[N];
 10 long long first[N],nxt[N],cnt;
 11 void add(long long u,long long v){
 12     e[++cnt].u=u;
 13     e[cnt].v=v;
 14     nxt[cnt]=first[u];
 15     first[u]=cnt;
 16 }
 17 long long num[N],first1[N],nxt1[N],cnt1;
 18 void add2(long long u,long long v){
 19     e1[++cnt1].u=u;
 20     e1[cnt1].v=v;
 21     nxt1[cnt1]=first1[u];
 22     first1[u]=cnt1;
 23 }
 24 long long sign,bcc,low[N],dfn[N],stack[N],instack[N],top,siz[N],belong[N];
 25 void tarjan(long long x){
 26     low[x]=dfn[x]=++sign;
 27     instack[x]=1;
 28     stack[++top]=x;
 29     for(long long i=first[x];i;i=nxt[i]){
 30         long long v=e[i].v;
 31         if(!dfn[v]){
 32             tarjan(v);
 33             low[x]=min(low[x],low[v]);
 34         }
 35         else if(instack[v])low[x]=min(low[x],dfn[v]);
 36     }
 37     if(dfn[x]==low[x]){
 38         long long t;
 39         bcc++;
 40         do{
 41             t=stack[top--];
 42             belong[t]=bcc;
 43             instack[t]=0;
 44             siz[bcc]++;
 45         }while(t!=x);
 46     }
 47 }
 48 long long maxk[N];
 49 void dfs(long long x){
 50     maxk[x]=siz[x];
 51     long long max0=0;
 52     for(long long i=first1[x];i;i=nxt1[i]){
 53         long long v=e1[i].v;
 54         if(maxk[v]){
 55             max0=max(max0,maxk[v]);
 56             continue;
 57         }
 58         dfs(v);
 59         max0=max(max0,maxk[v]);
 60     }
 61     maxk[x]+=max0;
 62 }
 63 long long read(){
 64     long long x=0,f=1;
 65     char c=getchar();
 66     while(!isdigit(c)){
 67         if(c=='-')f=-1;
 68         c=getchar();
 69     }
 70     while(isdigit(c)){
 71         x=(x<<3)+(x<<1)+c-'0';
 72         c=getchar();
 73     }
 74     return x*f;
 75 }
 76 int main(){
 77     int siz=80<<20;
 78     __asm__ ("movq %0,%%rsp
"::"r"((char*)malloc(siz)+siz));
 79     n=read(),m=read();
 80     for(long long i=1;i<=m;i++){
 81         long long a,b;
 82         a=read(),b=read();
 83         add(a,b);
 84     }
 85     for(long long i=1;i<=n;i++){
 86         if(!dfn[i])tarjan(i);
 87     }
 88     for(long long i=1;i<=cnt;i++){
 89         long long u=e[i].u,v=e[i].v;
 90         if(belong[u]==belong[v])continue;
 91         add2(belong[u],belong[v]);
 92     }
 93     long long ans=0;
 94     for(long long i=1;i<=bcc;i++){
 95         if(!maxk[i])dfs(i);
 96         ans=max(ans,maxk[i]);
 97     }
 98     cout<<ans;
 99     exit(0);
100     return 0;
101 }

over