校园网

可以看出Tarjan缩点,但对于第一问,我竟然想到状压DP😢

对于第二问,我想的是怎么添边成环😢

对于第一问,统计入度为0的点即可

对于第二问,统计出度为0的点,与第一问取个max即可

                     因为要把所有点的入度出度都变成大于0的......

还有就是Tarjan缩点的写法,要用do while......

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<stack>
 4 using namespace std;
 5 const int maxn=107;
 6 int dfn[maxn],low[maxn],head[maxn],cnt[maxn],color[maxn];
 7 int n,tot,num,count,top=1,sta[maxn];
 8 int in[maxn],out[maxn],map[maxn][maxn];
 9 bool ins[maxn];
10 stack<int>s;
11 struct Edge{
12     int next,to;
13 }edge[maxn*maxn];
14 void addedge(int from,int to){
15     edge[++num].next=head[from];
16     edge[num].to=to;
17     head[from]=num;
18 }
19 void Tarjan(int u){
20     dfn[u]=low[u]=++tot;
21     s.push(u);ins[u]=true;
22     for(int i=head[u];i;i=edge[i].next){
23         int v=edge[i].to;
24         if(!dfn[v]){
25             Tarjan(v);
26             low[u]=min(low[u],low[v]);
27         }                             
28         else if(ins[v]){
29             low[u]=min(low[u],dfn[v]);
30         }             
31     }
32     int k;
33     if(low[u]==dfn[u]){
34         count++;
35         do{
36             k=s.top();s.pop();
37             color[k]=count;
38             ins[k]=false;
39         }while(k!=u);
40         
41     }
42 }
43 int main(){
44     cin>>n;
45     for(int i=1;i<=n;i++){
46         int a;cin>>a;
47         while(a!=0){
48             addedge(i,a);
49             cin>>a;
50         }
51     }
52     for(int i=1;i<=n;i++)
53         if(!dfn[i]) Tarjan(i);
54     for(int i=1;i<=n;i++){
55         for(int j=head[i];j;j=edge[j].next){
56             int v=edge[j].to;
57             if(color[i]!=color[v]){
58                 if(map[color[i]][color[v]]==0){
59                     in[color[v]]++;out[color[i]]++;
60                 }
61                 map[color[i]][color[v]]=1;
62             }
63         }
64     }
65     int ans1=0,ans2=0;
66     if(count==1) {cout<<1<<endl<<0<<endl;return 0;}
67     for(int i=1;i<=count;i++){
68         if(in[i]==0) ans1++;
69         if(out[i]==0) ans2++;
70     }
71     ans2=max(ans1,ans2);
72     cout<<ans1<<endl<<ans2<<endl;
73     return 0;
74 } 

记得要特判强连通分量就是本身的情况......

posted @ 2018-08-19 18:17  lcan  阅读(373)  评论(0编辑  收藏  举报