zoukankan      html  css  js  c++  java
  • POJ1236 Network of Schools 强连通分量

      题目链接:http://poj.org/problem?id=1236

      题意:向一些学校分配一种软件,有些学校获得软件后可以分配给其它学校(有向边),分别求:1.最少要分配多少个软件使得所有学校都能获得软件。2.最少要加几条边使得只要分配一个软件给其中任意一个学校,其它学校都能获得软件。

      对于第一个问题很好求,就是入度为0的强连通分量中的点的个数。对于第二问,就是加多少条边使得图是强联通的,考虑那么只要考虑入度为0和出度为0的强连通分量,使得他们能成环,那么就是它们之间的最大值,注意一个强连通分量时要特殊考虑。

      1 //STATUS:C++_AC_0MS_216KB
      2 #include <functional>
      3 #include <algorithm>
      4 #include <iostream>
      5 //#include <ext/rope>
      6 #include <fstream>
      7 #include <sstream>
      8 #include <iomanip>
      9 #include <numeric>
     10 #include <cstring>
     11 #include <cassert>
     12 #include <cstdio>
     13 #include <string>
     14 #include <vector>
     15 #include <bitset>
     16 #include <queue>
     17 #include <stack>
     18 #include <cmath>
     19 #include <ctime>
     20 #include <list>
     21 #include <set>
     22 #include <map>
     23 using namespace std;
     24 //define
     25 #define pii pair<int,int>
     26 #define mem(a,b) memset(a,b,sizeof(a))
     27 #define lson l,mid,rt<<1
     28 #define rson mid+1,r,rt<<1|1
     29 #define PI acos(-1.0)
     30 //typedef
     31 typedef __int64 LL;
     32 typedef unsigned __int64 ULL;
     33 //const
     34 const int N=110;
     35 const int INF=0x3f3f3f3f;
     36 const int MOD=100000,STA=8000010;
     37 const LL LNF=1LL<<60;
     38 const double EPS=1e-8;
     39 const double OO=1e15;
     40 const int dx[4]={-1,0,1,0};
     41 const int dy[4]={0,1,0,-1};
     42 //Daily Use ...
     43 inline int sign(double x){return (x>EPS)-(x<-EPS);}
     44 template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}
     45 template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}
     46 template<class T> inline T Min(T a,T b){return a<b?a:b;}
     47 template<class T> inline T Max(T a,T b){return a>b?a:b;}
     48 template<class T> inline T Min(T a,T b,T c){return min(min(a, b),c);}
     49 template<class T> inline T Max(T a,T b,T c){return max(max(a, b),c);}
     50 template<class T> inline T Min(T a,T b,T c,T d){return min(min(a, b),min(c,d));}
     51 template<class T> inline T Max(T a,T b,T c,T d){return max(max(a, b),max(c,d));}
     52 //End
     53 
     54 struct Edge{
     55     int u,v;
     56 }e[N*N];
     57 int first[N],next[N*N],pre[N],sccno[N],low[N],vis1[N],vis2[N];
     58 int n,mt,dfs_clock,scnt;
     59 stack<int> s;
     60 
     61 void adde(int a,int b)
     62 {
     63     e[mt].u=a;e[mt].v=b;
     64     next[mt]=first[a],first[a]=mt++;
     65 }
     66 
     67 void dfs(int u)
     68 {
     69     int i,j,v;
     70     pre[u]=low[u]=++dfs_clock;
     71     s.push(u);
     72     for(i=first[u];i!=-1;i=next[i]){
     73         v=e[i].v;
     74         if(!pre[v]){
     75             dfs(v);
     76             low[u]=Min(low[u],low[v]);
     77         }
     78         else if(!sccno[v]){
     79             low[u]=Min(low[u],low[v]);
     80         }
     81     }
     82     if(low[u]==pre[u]){
     83         int x=-1;
     84         scnt++;
     85         while(x!=u){
     86             x=s.top();s.pop();
     87             sccno[x]=scnt;
     88         }
     89     }
     90 }
     91 
     92 int main()
     93 {
     94  //   freopen("in.txt","r",stdin);
     95     int i,j,a,b,ans1,ans2;
     96     while(~scanf("%d",&n))
     97     {
     98         mem(first,-1);mt=0;
     99         for(i=1;i<=n;i++){
    100             while(scanf("%d",&a) && a)
    101                 adde(i,a);
    102         }
    103 
    104         mem(pre,0);mem(sccno,0);
    105         scnt=dfs_clock=0;
    106         for(i=1;i<=n;i++){
    107             if(!pre[i])dfs(i);
    108         }
    109         for(i=1;i<=scnt;i++)vis1[i]=vis2[i]=1;
    110         for(i=1;i<=n;i++){
    111             for(j=first[i];j!=-1;j=next[j]){
    112                 if(sccno[e[j].v]!=sccno[i]){
    113                     vis1[sccno[e[j].v]]=0;
    114                     vis2[sccno[i]]=0;
    115                 }
    116             }
    117         }
    118         ans1=ans2=0;
    119         for(i=1;i<=scnt;i++){
    120             ans1+=vis1[i];
    121             ans2+=vis2[i];
    122         }
    123 
    124         printf("%d\n%d\n",ans1,scnt==1?0:Max(ans1,ans2));
    125     }
    126     return 0;
    127 }
  • 相关阅读:
    在实践中培养学生学习软件工程的兴趣
    软件工程课程设计指导随笔
    软件工程——个人总结
    软件工程第二次作业——结对编程
    个人博客作业三:微软小娜APP的案例分析
    嵌入式软件设计第12次实验报告
    嵌入式软件设计第11次实验报告
    嵌入式软件设计第09实验报告
    嵌入式软件设计第10次实验报告
    嵌入式软件设计第7次实验报告8
  • 原文地址:https://www.cnblogs.com/zhsl/p/3090321.html
Copyright © 2011-2022 走看看