码迷,mamicode.com
首页 > 其他好文 > 详细

OJ 1234 校园网络

时间:2017-11-23 08:36:29      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:text   ==   有一个   read   cells   continue   std   limit   sdi   

     
 
From easthong
校园网络
 
     
     
  描述 Description  
  一些学校连入一个电脑网络。那些学校已订立了协议:每个学校都会给其它的一些学校分发软件(称作“接受学校”)。注意如果 B 在 A 学校的分发列表中,那么 A 不必也在 B 学校的列表中。

你要写一个程序计算,根据协议,为了让网络中所有的学校都用上新软件,必须接受新软件副本的最少学校数目(子任务 A)。更进一步,我们想要确定通过给任意一个学校发送新软件,这个软件就会分发到网络中的所有学校。为了完成这个任务,我们可能必须扩展接收学校列表,使其加入新成员。计算最少需要增加几个扩展,使得不论我们给哪个学校发送新软件,它都会到达其余所有的学校(子任务 B)。一个扩展就是在一个学校的接收学校列表中引入一个新成员。
     
     
  输入格式 Input Format  
  第一行包括一个整数 N:网络中的学校数目(2 <= N <= 100)。学校用前 N 个正整数标识。接下来 N 行中每行都表示一个接收学校列表(分发列表)。第 i+1 行包括学校 i 的接收学校的标识符。每个列表用 0 结束。空列表只用一个 0 表示。
     
     
  输出格式 Output Format  
  第一行应该包括一个正整数:子任务 A 的解。第二行应该包括子任务 B 的解。
     
     
  样例输入 Sample Input  
 
     
     
  样例输出 Sample Output  
 
     
     
  时间限制 Time Limitation  
  1s
     
     
  注释 Hint  
   
     
     
  来源 Source  
  usaco 5.3.3

这道题有两问

第一问很简单,先tarjin缩一下点,然后找出所有入度为0的点,那么这些点是必须要副本的,其他的点一定可以有这些点到达,所以答案就是所有入度为0的点

第二问,有一个小结论,就是一个有向图我们只需要最多连max(入度为0的点的个数,初度为0的点的个数)条边,那么个图就可以成为强连通的,即从任意一个点可以到达另外所有点,但当只有一个强连通分量的时候要输出0而不是1

技术分享图片
 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 inline int read(){
 5     int x=0;int f=1;char ch=getchar();
 6     while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
 7     while(isdigit(ch)) {x=x*10+ch-0;ch=getchar();}
 8     return x*f;
 9 }
10 const int MAXN=1e4+10;
11 namespace zhangenming{
12     struct node{
13           int x,y,next;
14     }e[MAXN];
15     int linkk[MAXN],len=0,n;
16     inline void insert(int xx,int yy){
17          e[++len].y=yy;e[len].x=xx;e[len].next=linkk[xx];linkk[xx]=len;
18     }
19    void init(){
20        n=read();
21        for(int i=1;i<=n;i++){
22         int xx=read(); 
23            while(xx){
24                insert(i,xx);
25             xx=read();
26            }    
27        }
28     }
29     int vis[MAXN],stark[MAXN],ine[MAXN],cntt[MAXN]={},tot=0,top=0,cnt[MAXN]={},dfn[MAXN]={},low[MAXN],dfs_clock=0;
30     inline void tarjin(int st){
31         //cout<<st<<endl;
32         dfn[st]=low[st]=++dfs_clock;vis[st]=1;
33         stark[++top]=st;
34         for(int i=linkk[st];i;i=e[i].next){
35             if(!dfn[e[i].y]){
36                 //cout<<e[i].y<<endl;
37                 tarjin(e[i].y);
38                 low[st]=min(low[st],low[e[i].y]);
39             }
40             else if(vis[e[i].y]) low[st]=min(low[st],dfn[e[i].y]);
41         }
42         if(low[st]==dfn[st]){
43             tot++;
44             int k;
45             do{
46                 k=stark[top--];
47                 ine[k]=tot;
48                 vis[k]=0;
49             }while(k!=st);
50         }
51     }
52     void solve(){
53         memset(vis,0,sizeof(vis));
54         for(int i=1;i<=n;i++){
55             if(!ine[i]) tarjin(i);
56         }
57         for(int i=1;i<=len;i++){
58             int xx=e[i].x;int yy=e[i].y;
59             if(ine[xx]==ine[yy]) continue;
60             cnt[ine[yy]]++;
61             cntt[ine[xx]]++;
62         }
63         int sum1=0;int sum2=0;
64         for(int i=1;i<=tot;i++){
65             if(!cnt[i]) sum1++;
66             if(!cntt[i]) sum2++;
67         }
68         cout<<sum1<<endl;
69         if(tot!=1) cout<<max(sum1,sum2)<<endl;
70         else cout<<0<<endl;
71     }
72 }
73 int main(){
74     using namespace zhangenming;
75     init();
76     solve();
77     return 0;
78 }
代码

 

OJ 1234 校园网络

标签:text   ==   有一个   read   cells   continue   std   limit   sdi   

原文地址:http://www.cnblogs.com/something-for-nothing/p/7881520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!