zoukankan      html  css  js  c++  java
  • UVALive-4287 Proving Equivalences 有向图的强连通分量+缩点

    题意:有n个命题,已知其中的m个推导,要证明n个命题全部等价(等价具有传递性),最少还需要做出几次推导。

    思路:由已知的推导可以建一张无向图,则问题变成了最少需要增加几条边能使图变成强连通图。找出所有的强连通分量,将每一个连通分量视作一个大节点,则整张图变成了一张DAG。设出度为0的大节点个数为b,入度为0的大节点个数为a,则答案就是max(a,b)。

      1 #include<iostream>
      2 #include<string>
      3 #include<algorithm>
      4 #include<cstdlib>
      5 #include<cstdio>
      6 #include<set>
      7 #include<map>
      8 #include<vector>
      9 #include<cstring>
     10 #include<stack>
     11 #include<cmath>
     12 #include<queue>
     13 #define clc(a,b) memset(a,b,sizeof(a))
     14 #include <bits/stdc++.h>
     15 using namespace std;
     16 #define LL long long
     17 const int maxn = 20005;
     18 const int inf=0x3f3f3f3f;
     19 const double pi=acos(-1);
     20 int  in[maxn],out[maxn];
     21 vector<int>G[maxn];
     22 int pre[maxn],lowlink[maxn],sccno[maxn],dfs_clock,scc_cnt;
     23 stack<int>S;
     24 
     25 void dfs(int u)
     26 {
     27     pre[u]=lowlink[u]=++dfs_clock;
     28     S.push(u);
     29     for(int i=0; i<G[u].size(); i++)
     30     {
     31         int v=G[u][i];
     32         if(!pre[v])
     33         {
     34             dfs(v);
     35             lowlink[u]=min(lowlink[u],lowlink[v]);
     36         }
     37         else if(!sccno[v])
     38         {
     39             lowlink[u]=min(lowlink[u],pre[v]);
     40         }
     41     }
     42     if(lowlink[u]==pre[u])
     43     {
     44         scc_cnt++;
     45         for(;;)
     46         {
     47             int x=S.top();
     48             S.pop();
     49             sccno[x]=scc_cnt;
     50             if(x==u)
     51                 break;
     52         }
     53     }
     54 }
     55 
     56 void find_scc(int n)
     57 {
     58     dfs_clock=scc_cnt=0;
     59     clc(sccno,0);
     60     clc(pre,0);
     61     for(int i=0; i<n; i++)
     62         if(!pre[i])
     63             dfs(i);
     64 }
     65 
     66 int main()
     67 {
     68     int t,n,m;
     69     scanf("%d",&t);
     70     while(t--)
     71     {
     72         scanf("%d%d",&n,&m);
     73         for(int i=0; i<n; i++)
     74             G[i].clear();
     75         for(int i=0; i<m; i++)
     76         {
     77             int u,v;
     78             scanf("%d%d",&u,&v);
     79             u--;
     80             v--;
     81             G[u].push_back(v);
     82         }
     83         find_scc(n);
     84         for(int i=1; i<=scc_cnt; i++)
     85             in[i]=out[i]=0;
     86         for(int u=0; u<n; u++)
     87         {
     88             for(int i=0; i<G[u].size(); i++)
     89             {
     90                 int v=G[u][i];
     91                 if(sccno[u]!=sccno[v])
     92                     in[sccno[v]]=out[sccno[u]]=1;
     93             }
     94         }
     95         int a=0,b=0;
     96         for(int i=1; i<=scc_cnt; i++)
     97         {
     98             if(!in[i])
     99                 a++;
    100             if(!out[i])
    101                 b++;
    102         }
    103         int ans=max(a,b);
    104         if(scc_cnt==1)
    105             ans=0;
    106         printf("%d
    ",ans);
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    2101 可达性统计
    POJ1179 Polygon
    POJ1015 Jury Compromise
    读入输出优化
    队列优化dijsktra(SPFA)的玄学优化
    5104 I-country
    CH5102 Mobile Service
    P1005 矩阵取数游戏
    (模板)线段树2
    POJ3666 Making the Grade
  • 原文地址:https://www.cnblogs.com/ITUPC/p/5215219.html
Copyright © 2011-2022 走看看