Bombing (bomb): tarjan, topological sorting

On the test questions wrong, nothing to say.

However, it is a big board.

Hair explanations can barely see. But I still want to talk about.

The expression subject if directly or indirectly from A to B, then it can not simultaneously A and B. bombing

So we just pulled from the figure in a directed path, this path arbitrarily pick two points AB, then either from A to B or from B to A

Then you pick any of the two points just not the same point that you can not bomb the same time.

He underlined that section of what use is it? Its correctness is obvious.

I said, "there is a path to" do not add any additional restrictions, it may include a ring, turn a few laps on the same point can occur chant.

We consider a simple ring. Then every single time it should be fried on.

Consider a simple path, each point on the path also requires a separate bombing.

If a path into a loop, then this point must be above a fried separate (point on the path to reach any point on the ring).

If a ring leads to a path, then a point on the ring also to the path, have a fried separately.

In summary, it is to find a path different from the above points as much as possible, the number of different points is the answer.

Above a bunch of words that already includes this meaning: each point on the path length of the ring to increase 1, and has no effect on connectivity.

End so consider tarjan condensing component after no strong link the ring, but the ring into a large dot is equal to the weight of only the number of points in the ring

The remaining ordinary right point value of 1. The question now becomes to find a path in a DAG in it right to the point and above the maximum.

Not dfs, because it is directed the DAG, although not a ring but not a tree, it can grow very sick.

In view of this disgusting inside run dfs will be repeated after three and three-point lead following a lot of waste.

Search backwards can add a memory of something, but a topological sort would be more convenient.

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 map<int,int>mm;
 4 int n,m,fir[1000005],l[1000005],to[1000005],cnt=1,dfn[1000005],low[1000005];
 5 int _fir[1000005],_l[1000005],_to[1000005],_cnt,w[1000005],in[1000005];
 6 int sta[1000005],ins[1000005],tim,top,bl[1000005],cnt_scc,ans,dis[1000005];
 7 int q[1000005],t;
 8 void connect(int a,int b){l[++cnt]=fir[a];fir[a]=cnt;to[cnt]=b;}
 9 void _connect(int a,int b){_l[++_cnt]=_fir[a];_fir[a]=_cnt;_to[_cnt]=b;in[b]++;}
10 void tarjan(int p){
11     dfn[p]=low[p]=++tim;sta[++top]=p;ins[p]=1;
12     for(int i=fir[p];i;i=l[i])
13         if(!dfn[to[i]])tarjan(to[i]),low[p]=min(low[p],low[to[i]]);
14         else if(ins[to[i]])low[p]=min(low[p],low[to[i]]);
15     if(dfn[p]==low[p]){
16         w[++cnt_scc]++;
17         while(sta[top]!=p)ins[sta[top]]=0,bl[sta[top--]]=cnt_scc,w[cnt_scc]++;
18         top--;bl[p]=cnt_scc;ins[p]=0;
19     }
20 }
21 signed main(){
22     scanf("%d%d",&n,&m);
23     for(int i=1,a,b;i<=m;++i)scanf("%d%d",&a,&b),connect(a,b);
24     for(int i=1;i<=n;++i)if(!dfn[i])tarjan(i);
25     for(int i=1;i<=n;++i)for(int j=fir[i];j;j=l[j])
26         if(bl[i]!=bl[to[j]])_connect(bl[i],bl[to[j]]);
27     for(int i=1;i<=cnt_scc;++i)if(!in[i])q[++t]=i;
28     for(int h=1;h<=t;++h){
29         int dt=dis[q[h]]+w[q[h]];ans=max(ans,dt);
30         for(int i=_fir[q[h]];i;i=_l[i]){
31             in[_to[i]]--;dis[_to[i]]=max(dis[_to[i]],dt);
32             if(!in[_to[i]])q[++t]=_to[i];
33         }
34     }
35     printf("%d\n",ans);
36 }
In fact, the code size is not large

 

Guess you like

Origin www.cnblogs.com/hzoi-DeepinC/p/11328385.html