zoukankan      html  css  js  c++  java
  • 强连通 HDU 3861

    t个样例

    n个点m条边

    分成一些区

    2个点互相能到达必须分在一个区

    一个区中任何2个点可以u->v 或者v->u

    任何点都要有自己的区

    求最小的区的数目

    强联通缩点

    成新图

    二分匹配 求最大匹配

    最小路径覆盖=点数-最大匹配数

      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<string.h>
      4 #include<stack>
      5 
      6 using namespace std;
      7 
      8 #define MAXN 5010
      9 #define MAXN1 100010
     10 int head[MAXN],dfn[MAXN],low[MAXN],cou[MAXN],fa[MAXN];
     11 int cnt,k,num;
     12 bool vis[MAXN],mark[MAXN];
     13 
     14 struct edg
     15 {
     16     int next,to,fr;
     17 }x[MAXN1];
     18 void add(int u,int v)
     19 {
     20     x[cnt].next=head[u];
     21     x[cnt].fr=u;
     22     x[cnt].to=v;
     23     head[u]=cnt++;
     24 }
     25 stack<int>s;
     26 
     27 void dfs(int u)
     28 {
     29     low[u]=dfn[u]=k++;
     30     vis[u]=1;
     31     s.push(u);
     32     int i;
     33     for(i=head[u];i!=-1;i=x[i].next)
     34     {
     35         int v=x[i].to;
     36         if(!dfn[v])
     37         {
     38             dfs(v);
     39             low[u]=min(low[u],low[v]);
     40         }
     41         else if(vis[v])
     42             low[u]=min(low[u],dfn[v]);
     43     }
     44     if(dfn[u]==low[u])
     45     {
     46         num++;
     47         while(!s.empty())
     48         {
     49             int now=s.top();
     50             s.pop();
     51             vis[now]=0;
     52             fa[now]=num;
     53             if(now==u)break;
     54         }
     55     }
     56 }
     57 int pa[MAXN];
     58 
     59 bool dfs1(int u)
     60 {
     61     int i;
     62     for(i=head[u];i!=-1;i=x[i].next)
     63     {
     64         if(mark[x[i].to])
     65             continue;
     66         mark[x[i].to]=1;
     67         if(pa[x[i].to]==-1||dfs1(pa[x[i].to]))
     68         {
     69             pa[x[i].to]=u;
     70             return 1;
     71         }
     72     }
     73     return 0; //很重要
     74 }
     75 int main()
     76 {
     77     int t;
     78     scanf("%d",&t);
     79 
     80     while(t--)
     81     {
     82         int n,m,i;
     83         scanf("%d%d",&n,&m);
     84         cnt=0;
     85         memset(head,-1,sizeof(head));
     86         memset(dfn,0,sizeof(dfn));
     87         memset(low,0,sizeof(low));
     88 
     89         for(i=1;i<=m;i++)
     90         {
     91             int a,b;
     92             scanf("%d%d",&a,&b);
     93             add(a,b);
     94         }
     95         k=1;
     96         num=0;
     97         for(i=1;i<=n;i++) //强联通
     98             if(!dfn[i])
     99                 dfs(i);
    100         memset(head,-1,sizeof(head));
    101         memset(pa,-1,sizeof(pa));
    102         int en=cnt;
    103         cnt=0;
    104         for(i=0;i<en;i++)
    105         {
    106             int u,v;
    107             u=fa[x[i].fr];
    108             v=fa[x[i].to];
    109             if(u!=v)
    110             {
    111                 add(u,v);
    112             }
    113         }
    114         int ans=0;
    115 
    116         for(i=1;i<=num;i++) //二分匹配
    117         {
    118             memset(mark,0,sizeof(mark));
    119             if(dfs1(i))
    120                 ans++;
    121         }
    122         printf("%d
    ",num-ans);
    123     }
    124 
    125     return 0;
    126 }
  • 相关阅读:
    Webpack2 那些路径
    Nginx alias 和 root配置
    前端代码监控
    Class和构造函数的异同
    Async和await
    如何在git中删除指定的文件和目录
    微信小程序数字转化条形码和二维码
    vue 结合swiper插件实现广告公告上下滚动的效果
    vue2.0 结合better-scroll 实现下拉加载
    FormData对象提交表单和form提交表单
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6067450.html
Copyright © 2011-2022 走看看