• 【bzoj4484】【jsoi2015】最小表示


    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 432  Solved: 223
    [Submit][Status][Discuss]

    Description

    【故事背景】
    还记得去年JYY所研究的强连通分量的问题吗?去年的题目里,JYY研究了对于有向图的“加边”问题。对于图论有着强烈兴趣的JYY,今年又琢磨起了“删边”的问题。
    【问题描述】
    对于一个N个点(每个点从1到N编号),M条边的有向图,JYY发现,如果从图中删去一些边,那么原图的连通性会发生改变;而也有一些边,删去之后图的连通性并不会发生改变。
    JYY想知道,如果想要使得原图任意两点的连通性保持不变,我们最多能删掉多少条边呢?
    为了简化一下大家的工作量,这次JYY保证他给定的有向图一定是一个有向无环图(JYY:大家经过去年的问题,都知道对于给任意有向图的问题,最后都能转化为有向无环图上的问题,所以今年JYY就干脆简化一下大家的工作)。

    Input

    输入一行包含两个正整数N和M。
    接下来M行,每行包含两个1到N之间的正整数x_i和y_i,表示图中存在一条从x_i到y_i的有向边。
    输入数据保证,任意两点间只会有至多一条边存在。
    N<=30,000,M<=100,000

    Output

    输出一行包含一个整数,表示JYY最多可以删掉的边数。

    Sample Input

    5 6

    1 2

    2 3

    3 5

    4 5

    1 5

    1 3

    Sample Output

    2

    HINT

     

    Source

    [Submit][Status][Discuss]

    题解 :
            cmp函数:不加类型的话本地不会编译错误,(il好像也是);

            删边互相之间是无影响的,所以可删就删,和顺序无关; 
            由于没有重边的无环DAG,一条边可删即这条边的u,v有另一种方式到达;
            DAG转成topsort序列,bitset优化N*M连通性dp
            $O( frac{NM}{64} + M*logM)$
            //毕姥爷说得对,还是写一下的好,不然连bitset的空间都不会开(和vector一样);
            20181031

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<queue>
     6 #include<cmath>
     7 #include<vector>
     8 #include<stack>
     9 #include<map>
    10 #include<bitset>
    11 #define rg register
    12 #define il inline 
    13 #define Run(i,l,r) for(int i=l;i<=r;i++)
    14 #define Don(i,l,r) for(int i=l;i>=r;i--)
    15 #define ll long long
    16 #define ld long double
    17 #define inf 0x3f3f3f3f
    18 using namespace std;
    19 const int N=30001 , M=100010;
    20 bitset<N>f[N];
    21 int n,m,o,hd[N],st[N],id[N],d[N],idx,q[N],t,w;
    22 vector<int>g[N];
    23 char gc(){
    24     static char*p1,*p2,s[1000000];
    25     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
    26     return(p1==p2)?EOF:*p1++;
    27 }
    28 int rd(){
    29     int x=0; char c=gc();
    30     while(c<'0'||c>'9')c=gc();
    31     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
    32     return x;
    33 }
    34 il bool cmp(const int &a,const int &b){return id[a]<id[b];}
    35 il void topsort(){
    36     for(rg int i=1;i<=n;i++)if(!d[i])q[++w]=i;
    37     while(t<w){
    38         int u=q[++t];
    39         st[id[u]=++idx]=u;
    40         for(rg int i=0;i<(int)g[u].size();i++){
    41             int v=g[u][i];
    42             if(!--d[v]){
    43                 q[++w]=v;
    44             }
    45         }
    46     }
    47 }
    48 int main(){
    49     freopen("in.in","r",stdin);
    50     freopen("out.out","w",stdout);
    51     n=rd(); m=rd();
    52     for(rg int i=1,u,v;i<=m;i++){
    53         u=rd(); v=rd();
    54         g[u].push_back(v); 
    55         d[v]++;
    56     }
    57     topsort();
    58     for(rg int i=1;i<=n;i++){
    59         sort(g[i].begin(),g[i].end(),cmp);
    60     }
    61     int ans=0;
    62     for(rg int i=n;i;i--){
    63         int u=st[i];
    64         for(rg int j=0;j<(int)g[u].size();j++){
    65             int v=g[u][j];
    66             if(f[u].test(id[v])){
    67                 ans++;
    68             }else{
    69                 f[u][id[v]]=1;
    70                 f[u]|=f[v];
    71             }
    72         }
    73     }
    74     cout<<ans<<endl;
    75     return 0;
    76 }//by tkys_Austin;
    View Code
  • 相关阅读:
    类的无参方法
    类和对象的案例
    类和对象的实例
    类和对象
    【Java】【1】String数组和List相互转换
    【Oracle】【5】去掉字符串最后一个特殊字符
    【其他】【Restful】【1】简单了解Restful概念
    【IDEA】【7】Git更新及提交
    【IDEA】【6】Maven打包
    【IDEA】【5】快捷键
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/9901991.html
Copyright © 2020-2023  润新知