E - Reachability from the Capital

题目链接:https://vjudge.net/contest/236513#problem/E
大意:给你n条边的关系,输入的第一个只指向第一个,然后让你判断要想从指定的点到达剩下的所有的点,问你最少需要添加多少条边才符合要求。

思路:首先使用tarjan算法进行染色,缩点。到最后判断 缩减后 入度为零的不含有城市中心的强连通子图的个数就可以了!!!

原因,染完色之后,如果有入度为0的强连通子图,那么这个点就可能符合,然后吧满足这些条件的记录一下。注意,在累加 的时候,不能将入度为0的含有城市中心的强连通子图计算在内,因为这个图中,有城市中心的强连通图中,这个图中的其他所有的点都能由城市中心到达,所以不用累加。

代码如下:

 

  1 #include<iostream>
  2 #include<string>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #include<map>
  7 #include<vector>
  8 #include<stack>
  9 #include<queue>
 10 using namespace std;
 11 # define maxn 5005
 12 vector<int >wakaka[maxn];
 13 map<int,int>p;
 14 stack<int>q;
 15 int dfn[maxn],low[maxn],vis[maxn];
 16 int out[maxn],cnt[maxn],color[maxn],in[maxn];
 17 int num,ans;
 18 void tarjan(int u)
 19 {
 20     vis[u]=1;
 21     q.push(u);
 22     low[u]=dfn[u]=++num;
 23     int len=wakaka[u].size();
 24     for(int i=0; i<len; i++)
 25     {
 26         int v=wakaka[u][i];
 27         if(vis[v]==0)
 28         {
 29             tarjan(v);
 30             low[u]=min(low[u],low[v]);
 31         }
 32         if(vis[v]==1)
 33         {
 34             low[u]=min(low[u],dfn[v]);
 35         }
 36     }
 37     if(low[u]==dfn[u])
 38     {
 39         ans++;
 40         int top;
 41         do
 42         {
 43             top=q.top();
 44             q.pop();
 45             vis[top]=-1;
 46             color[top]=ans;
 47         }
 48         while(top!=u);
 49     }
 50 }
 51 int main()
 52 {
 53     int n,m,t;
 54     while(cin>>n>>m>>t)
 55     {
 56         num=ans=0;
 57         memset(vis,0,sizeof(vis));
 58         memset(cnt,0,sizeof(cnt));
 59         memset(out,0,sizeof(out));
 60         memset(in,0,sizeof(in));
 61         memset(color,0,sizeof(color));
 62         while(!q.empty())q.pop();
 63         for(int i=1; i<=n; i++)
 64         {
 65             wakaka[i].clear();
 66         }
 67         p.clear();
 68         for(int i=1; i<=m; i++)
 69         {
 70             int u,v;
 71             cin>>u>>v;
 72             p[u]++;
 73             p[v]++;
 74             wakaka[u].push_back(v);
 75         }
 76         for(int i=1; i<=n; i++)
 77         {
 78             if(vis[i]==0)
 79                 tarjan(i);
 80         }
 81         //cout<<color[1]<<endl<<color[2]<<endl;
 82         for(int i=1; i<=n; i++)
 83         {
 84             int len=wakaka[i].size();
 85             for(int j=0; j<len; j++)
 86             {
 87                 if(color[i]!=color[wakaka[i][j]])
 88                 {
 89                     in[color[i]]++;
 90                     out[color[wakaka[i][j]]]++;
 91                 }
 92             }
 93             cnt[color[i]]++;
 94         }
 95             int t1=0,t2=0;
 96             for(int i=1; i<=ans; i++)
 97             {
 98                 if(in[i]==0)
 99                     t1++;
100                 if(out[i]==0&&i!=color[t])
101                 {
102                     t2++;
103                 }
104             }
105             cout<<t2<<endl;
106             //else {
107             //cout<<max(t1,t2)<<endl;
108             //}
109             //}
110         }
111         return 0;
112     }
113 
114  

 

posted @ 2018-07-04 00:17  Let_Life_Stop  阅读(194)  评论(0)    收藏  举报