zoukankan      html  css  js  c++  java
  • Bzoj4484 [Jsoi2015]最小表示

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 103  Solved: 65

    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

    图论 拓扑排序 bitset

    将有向图拓扑排序,易知每条有向边只会从拓扑序小的点连向拓扑序大的点。

    按照拓扑序倒序处理每一个点,将当前点指向的所有点按拓扑序从小到大排序,贪心加边,若当前目标点已经被连通,就不需要加这条边。

    用bitset维护连通性十分方便。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<bitset>
     7 using namespace std;
     8 const int mxn=100010;
     9 int read(){
    10     int x=0,f=1;char ch=getchar();
    11     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    12     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    13     return x*f;
    14 }
    15 struct edge{
    16     int v,nxt;
    17 }e[mxn<<1];
    18 int hd[mxn],mct=0;
    19 void add_edge(int u,int v){
    20     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;return;
    21 }
    22 int q[mxn],hed,tl;
    23 int ind[mxn],id[mxn];
    24 int n,m;
    25 void topo(){
    26     hed=1;tl=0;
    27     for(int i=1;i<=n;i++)if(!ind[i])q[++tl]=i;
    28     while(hed<=tl){
    29         int u=q[hed];hed++;
    30         for(int i=hd[u];i;i=e[i].nxt){
    31             int v=e[i].v;
    32             --ind[v];
    33             if(!ind[v]){q[++tl]=v;}
    34         }
    35     }
    36     for(int i=1;i<=tl;i++)id[q[i]]=i;
    37     return;
    38 }
    39 int cmp(int a,int b){
    40     return id[a]<id[b];
    41 }
    42 bitset<30010>b[30010];
    43 int st[mxn],top=0;
    44 int ans=0;
    45 void solve(){
    46     int i,j;
    47     for(i=tl;i;i--){
    48         int u=q[i];
    49         b[u][u]=1;top=0;
    50         for(int j=hd[u];j;j=e[j].nxt)
    51             st[++top]=e[j].v;
    52         sort(st+1,st+top+1,cmp);
    53         for(int j=1;j<=top;j++){
    54             if(b[u][st[j]])ans++;
    55             else b[u]|=b[st[j]];
    56         }
    57     }
    58     printf("%d
    ",ans);
    59     return;
    60 }
    61 int main(){
    62 //  freopen("in.txt","r",stdin);
    63     int i,j,u,v;
    64     n=read();m=read();
    65     for(i=1;i<=m;i++){
    66         u=read();v=read();
    67         add_edge(u,v);
    68         ++ind[v];
    69     }
    70     topo();
    71     solve();
    72     return 0;
    73 }
  • 相关阅读:
    转载在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
    笔试题Multicore简答题(上)
    笔试题Multicore简答题(下)
    转载深入理解const char*p,char const*p,char *const p
    笔试题mulicore编程题
    躺在被窝看蜗居,一连看到大结局,饿了揪把馒头,咽不下去吃点咸菜,我一边吃馒头,一边吃咸菜,一把抹鼻涕,一把抹眼泪
    //向块中用程序添加属性
    带参数的多线程
    扩展数据名 删除
    无法加载程序集。错误详细信息: Autodesk.AutoCAD.Runtime.Exception: eDuplicateKey
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6925121.html
Copyright © 2011-2022 走看看