zoukankan      html  css  js  c++  java
  • poj 1236 Network of Schools(强连通、缩点、出入度)

    题意:给出一个有向图。1:问至少选出多少个点,才能沿有向边遍历所有节点。2:问至少加多少条有向边,使原图强连通。

    分析:第一个问题,缩点后找所有树根(入度为0)。第二个问题,分别找出入度为0和出度为0的所有点,去最大值即为答案。

      关于第二个问题,与这道题很相似。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<stack>
      4 #include<algorithm>
      5 using namespace std;
      6 
      7 const int MAXN=111;
      8 
      9 struct Edge{
     10     int v,next;
     11     Edge(){}
     12     Edge(int _v,int _next):v(_v),next(_next){}
     13 }edge[MAXN*MAXN];
     14 
     15 int pre[MAXN],low[MAXN],sccno[MAXN],dfs_clock,scc_cnt;
     16 int head[MAXN],tol;
     17 
     18 int outmark[MAXN],inmark[MAXN];
     19 
     20 stack<int>stk;
     21 
     22 void init()
     23 {
     24     tol=0;
     25     memset(head,-1,sizeof(head));
     26 }
     27 
     28 void add(int u,int v)
     29 {
     30     edge[tol]=Edge(v,head[u]);
     31     head[u]=tol++;
     32 }
     33 
     34 void dfs(int u)
     35 {
     36     int v;
     37     pre[u]=low[u]=++dfs_clock;
     38     stk.push(u);
     39     for(int i=head[u];i!=-1;i=edge[i].next)
     40     {
     41         v=edge[i].v;
     42 
     43         if(!pre[v]){
     44             dfs(v);
     45             low[u]=min(low[u],low[v]);
     46         }else if(!sccno[v])
     47             low[u]=min(low[u],pre[v]);
     48     }
     49     if(pre[u]==low[u]){
     50         scc_cnt++;
     51         do{
     52             v=stk.top();
     53             stk.pop();
     54             sccno[v]=scc_cnt;
     55         }while(u!=v);
     56     }
     57 }
     58 
     59 void find_scc(int n)
     60 {
     61     dfs_clock=scc_cnt=0;
     62     memset(pre,0,sizeof(pre));
     63     memset(low,0,sizeof(low));
     64     memset(sccno,0,sizeof(sccno));
     65 
     66     for(int i=1;i<=n;i++)
     67         if(!pre[i])
     68             dfs(i);
     69 }
     70 
     71 int main()
     72 {
     73     int n;
     74     scanf("%d",&n);
     75     init();
     76     for(int u=1;u<=n;u++)
     77     {
     78         while(1)
     79         {
     80             int v;
     81             scanf("%d",&v);
     82             if(!v)
     83                 break;
     84             add(u,v);
     85         }
     86     }
     87 
     88     find_scc(n);
     89 
     90     memset(inmark,0,sizeof(inmark));
     91     memset(outmark,0,sizeof(outmark));
     92     for(int i=1;i<=n;i++)
     93     {
     94         for(int j=head[i];j!=-1;j=edge[j].next)
     95             if(sccno[i]!=sccno[edge[j].v]){
     96                 inmark[sccno[edge[j].v]]++;
     97                 outmark[sccno[i]]++;
     98             }
     99     }
    100     int inans=0,outans=0;
    101     for(int i=1;i<=scc_cnt;i++)
    102     {
    103         if(!inmark[i])
    104             inans++;
    105         if(!outmark[i])
    106             outans++;
    107     }
    108     printf("%d
    ",inans);
    109     if(scc_cnt==1)
    110         printf("0
    ");
    111     else
    112         printf("%d
    ",max(inans,outans));
    113     return 0;
    114 }
    View Code
  • 相关阅读:
    loadrunner压测java请求
    Omnitty的使用
    软件工程之感想
    《人月神话》读后感
    my idea之NSBC分析
    电梯调度 总结稿 刘博&徐梦迪
    敏捷开发综述
    数组最大子数组和(续)之动态规划
    求二维数组最大子数组和 刘博&徐梦迪
    数组中的最大子数组的和 刘博&徐梦迪
  • 原文地址:https://www.cnblogs.com/zstu-abc/p/3349408.html
Copyright © 2011-2022 走看看