【bzoj4484】【JSOI2015】【最小表示】【拓扑排序+bitset】

来源:互联网 发布:优秀的杂志阅读软件 编辑:程序博客网 时间:2024/06/05 19:27

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

题解:

先求出这个图的拓扑序.

按拓扑序倒着做.中途可以求出一个点到出度为0的点的最大距离.

访问到一个点x的时候.

把它所有指向的点按之前求的距离从大到小排序.

然后枚举每个它指向点.如果这个点在之前已经可以从当前点访问到,那这条边显然多余.

用bitset维护一下每个点和其他点的联通情况即可.

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<bitset>#include<algorithm>#define N 30010#define M 100010 using namespace std;int point[N],n,m,x,y,t,next[M],d[N],q[N],cnt,len[N],end,ans;bitset<N>bit[N];struct edge{int st,en;}e[M];struct use{int en,v;}a[N];inline int read(){  int x(0);char ch=getchar();  while (ch<'0'||ch>'9') ch=getchar();  while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();  return x; }  inline void add(int x,int y){   next[++cnt]=point[x];point[x]=cnt;   e[cnt].st=x;e[cnt].en=y; }inline bool cmp(use a,use b){   return a.v>b.v;}inline void solve(){  int h(0),t(0),num(0);  for (int i=1;i<=n;i++) if (!d[i]) q[++t]=i;  while (h<t){    int u=q[++h];    for (int i=point[u];i;i=next[i]){      d[e[i].en]--;if (!d[e[i].en]) q[++t]=e[i].en;}   }   for (int i=t;i>=1;i--){    int u=q[i];bit[u][u]=1;num=0;len[u]=1;     for (int j=point[u];j;j=next[j]){      a[++num]=use{e[j].en,len[e[j].en]};  len[u]=max(len[u],len[e[j].en]+1);  }    sort(a+1,a+num+1,cmp);    for (int j=1;j<=num;j++){      int y=a[j].en;//cout<<u<<' '<<y<<endl;      if (bit[u][y]) ans++;      bit[u]|=bit[y];    }    } }int main(){  n=read();m=read();  for (int i=1;i<=m;i++){    x=read();y=read();    add(x,y);d[y]++;  }  solve();  cout<<ans<<endl;} 


0 0
原创粉丝点击