zoukankan      html  css  js  c++  java
  • hdu4635Strongly connected

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

    tarjan缩点 统计缩点后每个结点的出度入度 将那个包含原来点数最少的 且出度或者入度为0的大节点看作一个整体内部连边n*(n-1)个 连全部的; 其它的点为一整体连全部的 再两者连一同向的边 保证它的出度或者入度依旧为0的情况下任意连 最后减去原来的边M

      1 #include <iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<stdlib.h>
      5 #include<stack>
      6 using namespace std;
      7 #define N 100010
      8 #define M 100010
      9 #define INF 0xfffffff
     10 int a[110][110];
     11 stack<int>s;
     12 struct node
     13 {
     14     int u,v,next;
     15 }ed[M*2];
     16 int scc,sccno[N],head[N],lowlink[N],pre[N],dep,num[N],x[M],y[M],din[N],dout[N],o;
     17 void init()
     18 {
     19     o = 0;
     20     memset(head,-1,sizeof(head));
     21 }
     22 void add(int u,int v)
     23 {
     24     ed[o].u = u;
     25     ed[o].v = v;
     26     ed[o].next = head[u];
     27     head[u] = o++;
     28 }
     29 void dfs(int u)
     30 {
     31     int i;
     32     lowlink[u] = pre[u] = ++dep;
     33     s.push(u);
     34     for( i = head[u] ; i != -1 ; i = ed[i].next)
     35     {
     36         int v = ed[i].v;
     37         if(!pre[v])
     38         {
     39             dfs(v);
     40             lowlink[u] = min(lowlink[u],lowlink[v]);
     41         }
     42         else if(!sccno[v])
     43         lowlink[u] = min(lowlink[u],pre[v]);
     44     }
     45     if(lowlink[u]==pre[u])
     46     {
     47         scc++;
     48         for(;;)
     49         {
     50             int x = s.top();
     51             s.pop();
     52             sccno[x] = scc;
     53             if(x==u) break;
     54         }
     55     }
     56 }
     57 void find_scc(int n)
     58 {
     59     for(int i = 1; i <= n ;i++)
     60     if(!pre[i])
     61     dfs(i);
     62 }
     63 int main()
     64 {
     65     int i,t,n,m,a,b,kk=0;
     66     cin>>t;
     67     while(t--)
     68     {
     69         init();kk++;
     70         memset(num,0,sizeof(num));
     71         memset(pre,0,sizeof(pre));
     72         memset(din,0,sizeof(din));
     73         memset(dout,0,sizeof(dout));
     74         memset(sccno,0,sizeof(sccno));
     75         scanf("%d%d",&n,&m);
     76         for(i = 1; i <= m ; i++)
     77         {
     78             scanf("%d%d",&a,&b);
     79             x[i] = a;y[i] = b;
     80             add(a,b);
     81         }
     82         scc=0;dep=0;
     83         find_scc(n);
     84         printf("Case %d: ",kk);
     85         if(scc==1)
     86         {
     87             cout<<"-1
    ";
     88             continue;
     89         }
     90         for(i = 1; i <= n ; i++)
     91         num[sccno[i]]++;
     92         for(i = 1; i <= m ;i++)
     93         {
     94             if(sccno[x[i]]!=sccno[y[i]])
     95             {
     96                 dout[sccno[x[i]]]++;
     97                 din[sccno[y[i]]]++;
     98             }
     99         }
    100         long long minz = INF;
    101         for(i = 1 ;i <= scc ; i++)
    102         if(minz>num[i]&&(din[i]==0||dout[i]==0))
    103         minz = num[i];
    104         long long ss=0;
    105         ss = minz*(minz-1)+(n-minz)*(n-minz-1)+minz*(n-minz);
    106         cout<<ss-m<<endl;
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    HDU1294 Rooted Trees Problem(整数划分 组合数学 DP)
    HDU2546 饭卡(背包)
    经典动态规划总结
    POJ1285 Combinations, Once Again(背包 排列组合)
    计数 组合数学总结
    莫队算法 2038: [2009国家集训队]小Z的袜子(hose)
    循环-24. 求给定序列前N项和之二
    循环-23. 找完数
    循环-22. 输出闰年
    循环-21. 求交错序列前N项和
  • 原文地址:https://www.cnblogs.com/shangyu/p/3232045.html
Copyright © 2011-2022 走看看