zoukankan      html  css  js  c++  java
  • 【HDOJ4635】【Tarjan缩点+思维】【经典】

    http://acm.hdu.edu.cn/showproblem.php?pid=4635

    Strongly connected

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3821    Accepted Submission(s): 1510

    Problem Description
    Give a simple directed graph with N nodes and M edges. Please tell me the maximum number of the edges you can add that the graph is still a simple directed graph. Also, after you add these edges, this graph must NOT be strongly connected.
    A simple directed graph is a directed graph having no multiple edges or graph loops.
    A strongly connected digraph is a directed graph in which it is possible to reach any node starting from any other node by traversing edges in the direction(s) in which they point. 
     
    Input
    The first line of date is an integer T, which is the number of the text cases.
    Then T cases follow, each case starts of two numbers N and M, 1<=N<=100000, 1<=M<=100000, representing the number of nodes and the number of edges, then M lines follow. Each line contains two integers x and y, means that there is a edge from x to y.
     
    Output
    For each case, you should output the maximum number of the edges you can add.
    If the original graph is strongly connected, just output -1.
     
    Sample Input
    3 3 3 1 2 2 3 3 1 3 3 1 2 2 3 1 3 6 6 1 2 2 3 3 1 4 5 5 6 6 4
     
    Sample Output
    Case 1: -1
    Case 2: 1
    Case 3: 15
    题目大意:给一个简单有向图,在图中加边,问在保证图不强连通的情况下最多能加多少边。
    题目分析:仔细考虑可知如果不连通,至少有两个强连通分量。而一个强连通分量最多有 N*(N-1)条边,所以这道题的最后答案应该是成为两个强连通分量。
    总边数为 sum=(n1-1)*n1+(n2-1)*n2+(n2*n1),(其中n1+n2=n)由于已经存在了m条边,所以最后答案是ans=sum-m;
    所以对于上述sum 的最大值求最大值可知应该使其中一个强连通分量的顶点数n1尽可能小,前提是这两个强连通分量之间没有强连通,即这两个强连通分量的入度或者出度为0。则在Tarjan求出各个强连通分量之后,再缩点统计各个强连通分量的入度和出度,最后找出顶点数最少的入度或者出度为0的强连通分量代入即可。
    【PS:一定要记得使用边数m时,不要用while(m--),可能会因为下面需要使用m而无限wa。】
      1 #include<iostream>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<queue>
      5 #include<stack>
      6 #include<vector>
      7 using namespace std;
      8 const int maxn=100005;//边的最大值 
      9 const int maxn1=100005;//顶点最大值 
     10 struct edge{
     11     int from;
     12     int to;
     13     int next;
     14 }EDGE[maxn];
     15 vector<int>vc[maxn1];
     16 int head[maxn1],dfn[maxn1],vis[maxn1],low[maxn1],col[maxn1],out[maxn1],in[maxn1],en[maxn1],stk[maxn1];//各个变量的意义可参照上篇博客
     17 int edge_cnt=0,tot1=0,tot2=0,scc_cnt=0,tot0=0;
     18 int n,m;
     19 void add(int x,int y)
     20 {
     21     EDGE[edge_cnt].from=x;    
     22     EDGE[edge_cnt].to=y;
     23     EDGE[edge_cnt].next=head[x];
     24     head[x]=edge_cnt++;
     25 }
     26 void Tarjan(int u)
     27 {
     28     low[u]=dfn[u]=++tot1;//注意tot1的初值必须是1【因为dfn必须为正数】,所以这里使用++tot1而不用tot1++;
     29     vis[u]=1;
     30     stk[++tot2]=u;
     31     for(int i = head[u]; i != -1  ; i = EDGE[i].next)
     32     {
     33         if(!dfn[EDGE[i].to]){
     34             Tarjan(EDGE[i].to);
     35             low[u]=min(low[u],low[EDGE[i].to]);
     36         }
     37         else if(vis[EDGE[i].to]){
     38             low[u]=min(low[u],low[EDGE[i].to]);
     39         }
     40     }
     41             if(low[u]==dfn[u]){
     42             int xx;
     43             scc_cnt++;//注意scc_cnt也是从1开始的,因为要染色,区别于为染色的0 
     44             do{
     45                 xx=stk[tot2--];
     46                 vc[scc_cnt].push_back(xx);
     47                 col[xx]=scc_cnt;
     48                 vis[xx]=0;
     49             }while(xx!=u);
     50         }
     51 }
     52 void INIT()
     53 {
     54     for(int i = 0 ; i < maxn1 ; i++)
     55     vc[i].clear();
     56     edge_cnt=0,tot1=0,tot2=0,scc_cnt=0,tot0=0;
     57     memset(head,-1,sizeof(head));
     58     memset(stk,0,sizeof(stk));
     59     memset(in,0,sizeof(in));
     60     memset(out,0,sizeof(out));
     61     memset(dfn,0,sizeof(dfn));
     62     memset(low,0,sizeof(low));
     63     memset(col,0,sizeof(col));     
     64  } 
     65   void suodian()//缩点
     66  {
     67      for(int i = 0 ; i < edge_cnt ; i++)
     68     {
     69         if(col[EDGE[i].from]!=col[EDGE[i].to])
     70         {
     71             in[col[EDGE[i].to]]++;//缩点
     72                out[col[EDGE[i].from]]++;
     73         }
     74     }    
     75   } 
     76 int main()
     77 {
     78     int t;
     79     scanf("%d",&t);
     80     int case1=1;
     81     while(t--)
     82     {    
     83         INIT(); 
     84         scanf("%d%d",&n,&m);
     85         int M=m;
     86         while(M--)
     87         {
     88             int a,b;
     89             scanf("%d%d",&a,&b);
     90             add(a,b);
     91         }
     92         for(int i = 1 ; i <= n ; i++)
     93         {
     94             if(!dfn[i]){
     95                 Tarjan(i);
     96             }
     97         }    printf("Case %d: ",case1++);
     98         if(scc_cnt==1)
     99         {
    100             printf("-1
    ");
    101         }
    102         else
    103         {
    104             suodian();
    105             int minn=-1;
    106             for(int i = 1 ; i <= scc_cnt ; i++)
    107             {
    108                 if(in[i]==0||out[i]==0)
    109                 {
    110                     int asd=vc[i].size();
    111                     if(minn==-1||minn>asd)
    112                     {
    113                         minn=asd;
    114                     }
    115                 }
    116             }
    117             cout << (n-minn)*(n-minn-1)+minn*(minn-1)+minn*(n-minn)-m<<endl;
    118         }
    119      } 
    120     return 0;
    121 }
     
     
  • 相关阅读:
    那海蓝蓝 微博
    林子雨老师团队《Architecture of a Database System》 中文版
    MySQL优化---DBA对MySQL优化的一些总结
    MySQL索引原理及慢查询优化 美团
    MySQL 调优基础:Linux内存管理 Linux文件系统 Linux 磁盘IO Linux网络
    pthread_mutex_t
    知数堂MYSQL优化课---CU论坛版主 DBA 博客
    MySQL通用优化 叶金荣!!!
    MySQL 之 Metadata Locking 研究
    MySQL 调优基础(三) Linux文件系统
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/9035144.html
Copyright © 2011-2022 走看看