zoukankan      html  css  js  c++  java
  • POJ 1236 Network of Schools —— (缩点的应用)

      题目大意:有N个学校和一些有向边将它们连结,求:

        1.最少需要向几个学校发放软件,使得他们中的每一个学校最终都能够获得软件。

        2.最少需要增加几条有向边使得可以从任意一个学校发放软件,使得每一个学校最终都能够获得软件。

      分析:

        1.缩点以后,找出入度为0的点的个数即可(因为没人可以给他们软件)。

        2.缩点以后,答案即是max(入度为0的点,出度为0的点)。因为只要另每一对入度为0和出度为0的点相连接即可。

      第二个问题也有无向图的版本,那样的话处理方法是:缩点以后,找出那些度为1的点,个数为cnt,向上整除2即可(即答案为(cnt+1)/2)。

      代码如下:

      1 #include <stdio.h>
      2 #include <stack>
      3 #include <algorithm>
      4 #include <string.h>
      5 #include <vector>
      6 using namespace std;
      7 
      8 const int N = 100+5;
      9 
     10 stack<int> S;
     11 int scc_cnt;  //强连通分量的个数
     12 int dfs_clock;    //访问到该节点的时间戳
     13 int belong[N];  //belong[i]表示i节点所属于第几个强连通分量
     14 int dfn[N];     //表示第i个节点被访问的时间
     15 int low[N];    //表示第i个节点的子节点所能访问到的最小的dfn值
     16 vector<int> G[N];
     17 int in[100+5],out[100+5];
     18 
     19 void dfs(int u)
     20 {
     21     dfn[u] = low[u] = ++dfs_clock;
     22     S.push(u);
     23     for(int i=0;i<G[u].size();i++)
     24     {
     25         int v = G[u][i];
     26         if(!dfn[v])
     27         {
     28             dfs(v);
     29             low[u] = min(low[u],low[v]);
     30         }
     31         else if(!belong[v])
     32         {
     33             low[u] = min(low[u],low[v]);
     34         }
     35     }
     36     if(low[u]==dfn[u])
     37     {
     38         scc_cnt++;
     39         for(;;)
     40         {
     41             int x = S.top();S.pop();
     42             belong[x] = scc_cnt;
     43             if(x==u) break;
     44         }
     45     }
     46 }
     47 
     48 void scc(int n)
     49 {
     50     memset(dfn,0,sizeof(dfn));
     51     memset(belong,0,sizeof(belong));
     52     dfs_clock = scc_cnt = 0;
     53     for(int i=1;i<=n;i++)
     54     {
     55         if(!dfn[i]) dfs(i);
     56     }
     57 }
     58 
     59 int main()
     60 {
     61     int n;
     62     while(scanf("%d",&n)==1)
     63     {
     64         memset(in,0,sizeof(in));
     65         memset(out,0,sizeof(out));
     66         for(int i=1;i<=n;i++) G[i].clear();
     67         for(int i=1;i<=n;i++)
     68         {
     69             int to;
     70             while(scanf("%d",&to)==1&&to)
     71             {
     72                 G[i].push_back(to);
     73             }
     74         }
     75         
     76         scc(n);
     77         if(scc_cnt==1)
     78         {
     79             puts("1
    0");
     80             continue;
     81         }
     82         for(int i=1;i<=n;i++)
     83         {
     84             for(int j=0;j<G[i].size();j++)
     85             {
     86                 int v = G[i][j];
     87                 if(belong[i]==belong[v]) continue;
     88                 in[belong[v]]++;
     89                 out[belong[i]]++;
     90             }
     91         }
     92         int incnt=0,outcnt=0;
     93         for(int i=1;i<=scc_cnt;i++)
     94         {
     95             if(!in[i]) incnt++;
     96             if(!out[i]) outcnt++;
     97         }
     98         printf("%d
    %d
    ",incnt,max(incnt,outcnt));
     99     }
    100     return 0;
    101 }
  • 相关阅读:
    一、cocos2d-x 3.0 final使用httpclient编译到android,须要用到的android.mk
    lvchange的available參数
    基于谱减法的声音去噪
    ios使用openUrl进行应用跳转
    linux下ssh免密登陆
    字体图标 icon font
    hdu 3642 Get The Treasury(扫描线)
    3D游戏引擎一 win32编程
    Codeforces 112B-Petya and Square(实现)
    动态规划 is beginning。。。。。。。。。
  • 原文地址:https://www.cnblogs.com/zzyDS/p/5627639.html
Copyright © 2011-2022 走看看