zoukankan      html  css  js  c++  java
  • HDU 4635 Strongly connected

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

    解题思路:

    题目大意是你能最多能添加多少边,使的这个图不是强连通图。其临界条件是差一条边成强连通图。

    可以把图分成两个强连通图,左边的一个强连通分量点个数为y,右边一个强连通分量的个数为x。

    然后x的所有点都与y的所有点都有x->y连线,没有y-x的连线。这就是最终答案。

    x+y=n

    x×(x-1)+y×(y-1)+x×y-m

    化简的 n×n-x×y-n-m,很明显只有|x-y|的绝对值越大,最终结果就越大。

    最后我们用Tarjan算法,进行缩点后可能形成现在这样的图

    很明显只有入度,或出度为零的点才能选做x,或y。

    实现代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 
      7 const int MAXN=100010;
      8 
      9 struct Edge{
     10     int to,next;
     11 }edges[MAXN];
     12 
     13 int head[MAXN],tot;
     14 
     15 void init(){
     16     memset(head,-1,sizeof(head));
     17     tot=0;
     18 }
     19 
     20 void addEdge(int u,int v){
     21     edges[tot].to=v;
     22     edges[tot].next=head[u];
     23     head[u]=tot++;
     24 }
     25 
     26 int DFN[MAXN],LOW[MAXN],Stack[MAXN],NUM[MAXN],Belong[MAXN];
     27 bool Instack[MAXN];
     28 int scc,Index,top;
     29 
     30 void Tarjan(int u){
     31     DFN[u]=LOW[u]=++Index;
     32     Stack[top++]=u;
     33     Instack[u]=true;
     34 
     35     int v;
     36     for(int i=head[u];i!=-1;i=edges[i].next){
     37          v=edges[i].to;
     38 
     39         if(!DFN[v]){
     40             Tarjan(v);
     41             if(LOW[u]>LOW[v])
     42                 LOW[u]=LOW[v];
     43         }else if(Instack[v]&&LOW[u]>DFN[v]) LOW[u]=DFN[v];
     44     }
     45 
     46     if(LOW[u]==DFN[u]){
     47         scc++;
     48         do{
     49             v=Stack[--top];
     50             NUM[scc]++;
     51             Instack[v]=false;
     52             Belong[v]=scc;
     53         }while(v!=u);
     54     }
     55 }
     56 
     57 int in[MAXN],out[MAXN];
     58 void solve(long long n,long long m){
     59     memset(DFN,0,sizeof(DFN));
     60     memset(NUM,0,sizeof(NUM));
     61     memset(Instack,0,sizeof(Instack));
     62     top=Index=scc=0;
     63 
     64     for(int i=1;i<=n;i++)
     65         if(!DFN[i])
     66             Tarjan(i);
     67 
     68     if(scc==1){
     69         cout<<-1<<endl;
     70         return;
     71     }
     72 
     73     memset(in,0,sizeof(in));
     74     memset(out,0,sizeof(out));
     75 
     76     for(int i=1;i<=n;i++)
     77     for(int j=head[i];j!=-1;j=edges[j].next){
     78         int v=edges[j].to;
     79         if(Belong[i]!=Belong[v]){
     80             out[Belong[i]]++;
     81             in[Belong[v]]++;
     82         }
     83     }
     84 
     85     long long ans=0;
     86 
     87     for(int i=1;i<=scc;i++){
     88         if(in[i]==0||out[i]==0){
     89             ans=max(ans,(n*n-(n-NUM[i])*NUM[i]-n-m));
     90         }
     91     }
     92 
     93     //注意数据溢出的情况
     94 
     95     printf("%lld
    ",ans);
     96 }
     97 
     98 
     99 int main(){
    100     int T;
    101     scanf("%d",&T);
    102     for(int i=1;i<=T;i++){
    103 
    104         init();
    105         int n,m;
    106         scanf("%d%d",&n,&m);
    107         for(int j=0;j<m;j++){
    108             int u,v;
    109             scanf("%d%d",&u,&v);
    110             addEdge(u,v);
    111         }
    112         printf("Case %d: ",i);
    113         solve(n,m);
    114 
    115     }
    116 }
    自己选的路,跪着也要把它走完------ACM坑
  • 相关阅读:
    Pick-up sticks
    The Doors
    Intersecting Lines
    Segments
    TOYS
    Palindrome
    Distinct Substrings
    Milk Patterns
    Musical Theme
    JavaScript基于时间的动画算法
  • 原文地址:https://www.cnblogs.com/IKnowYou0/p/6539134.html
Copyright © 2011-2022 走看看