zoukankan      html  css  js  c++  java
  • HDU

    Strongly connected HDU - 4635 

    题意:给你一个n个点m条边的有向简单图,问最多加多少边使得图还是一个简单图,并且整个图不是一个强连通,如果原先整个图就是个强连通,就输出-1。

    首先要知道的是简单图,没有重边,而且没有自环,但是有其他的环。这样先不考虑整个图最终不是一个强连通,我们最多就可以加n*(n-1)-m,也是每个点向其他点连一条边,然后减去原来已经有的。

    然后我们来考虑让整个图不是强连通,我们先把其他子强连通求出来这样缩点之后就是一棵树了。那我们原先要让它变成一个强连通的话,就是入度为零和出度为零的点互相连边,然后多出来的可以任意向其他点连边,

    那现在不让它是强连通,并且要能加最多的边的话,我们就剩下一个入度为0或者出度为0的点不连即可。这样不连的边就是这个点向其他点连的边,也就是这个强连通里的点数*剩下的点数,所以我们需要统计下每个点(强连通)的大小,

    这样就是找所有入度或者出度为0的点 大小*(n-大小)最小的那一个,然后减去便可。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 const int N=1e5+11;
     6 struct Side{
     7     int v,ne;
     8 }S[N];
     9 bool ins[N];
    10 int n,m,sn,dn,head[N],dfn[N],low[N];
    11 int cn,tn,col[N],sta[N],size[N],in[N],out[N];
    12 void init(){
    13     sn=dn=cn=tn=0;
    14     for(int i=0;i<=n;i++){
    15         head[i]=-1;
    16         dfn[i]=0;
    17         ins[i]=false;
    18     }
    19 }
    20 void add(int u,int v){
    21     S[sn].v=v;
    22     S[sn].ne=head[u];
    23     head[u]=sn++;
    24 }
    25 void tarjan(int u){
    26     dfn[u]=low[u]=++dn;
    27     ins[u]=true;
    28     sta[++tn]=u;
    29     for(int i=head[u],v;~i;i=S[i].ne){
    30         v=S[i].v;
    31         if(!dfn[v]){
    32             tarjan(v);
    33             low[u]=min(low[u],low[v]);
    34         }else if(ins[v]) low[u]=min(low[u],dfn[v]);
    35     }
    36     if(dfn[u]==low[u]){
    37         col[u]=++cn;
    38         size[cn]=1;
    39         ins[u]=false;
    40         while(sta[tn]!=u){
    41             col[sta[tn]]=cn;
    42             size[cn]++;
    43             ins[sta[tn--]]=false;
    44         }
    45         tn--;
    46     }
    47 }
    48 ll solve(){
    49     for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    50     if(cn==1) return -1;
    51     ll ans=1ll*n*(n-1)-m,mins=1e18+9;
    52     for(int i=1;i<=cn;i++) in[i]=out[i]=0;
    53     for(int i=1,ci,cj;i<=n;i++){
    54         ci=col[i];
    55         for(int j=head[i];~j;j=S[j].ne){
    56             cj=col[S[j].v];
    57             if(ci!=cj){
    58                 in[cj]++;
    59                 out[ci]++;
    60             }
    61         }
    62     }
    63     for(int i=1;i<=cn;i++)
    64         if(!in[i]||!out[i]) mins=min(mins,1ll*size[i]*(n-size[i]));
    65     return ans-mins;
    66 }
    67 int main() {
    68     int t=1,T,u,v;
    69     scanf("%d",&T);
    70     while(t<=T){
    71         scanf("%d%d",&n,&m);
    72         init();
    73         for(int i=0;i<m;i++){
    74             scanf("%d%d",&u,&v);
    75             add(u,v);
    76         }
    77         printf("Case %d: %lld
    ",t++,solve());
    78     }
    79     return 0;
    80 }
    连边边
  • 相关阅读:
    Hibernate表中多对多关系的映射
    Servlet JDBC工具类
    访问gridview中的各类控件
    ASP.NET2.0中Gridview中的内容导出到Excel
    List<T> 分页方式,泛型分页方式
    VS保存和编译问题] 总是出现另一个程序正在使用此文件,进程无法访问
    JS实现DIV的增加和移动
    让Editplus调试PHP程序
    与UpdatePanel控件不兼容的控件
    在Powerdesigner中,根据已有字段的Name值替换Code相同的Name的值
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/11649508.html
Copyright © 2011-2022 走看看