bzoj 4484 [Jsoi2015]最小表示
2017-05-30 22:36
363 查看
4484: [Jsoi2015]最小表示
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 103 Solved: 65
[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
By 佚名上传
【分析】
拓扑排序+bitset
先把拓扑序搞出来,然后拓扑倒序用bitset维护u所能到达的点的集合。
【代码】
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 103 Solved: 65
[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
By 佚名上传
【分析】
拓扑排序+bitset
先把拓扑序搞出来,然后拓扑倒序用bitset维护u所能到达的点的集合。
【代码】
//bzoj 4484 #include<queue> #include<bitset> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define M(a) memset(a,0,sizeof a) #define fo(i,j,k) for(i=j;i<=k;i++) using namespace std; const int mxn=30005; bitset <mxn> b[mxn]; queue <int> q; int n,m,cnt,tot,ans; int c[mxn],head[mxn],du[mxn],num[mxn],map[mxn]; struct edge {int to,next;} f[200005]; inline bool comp(int x,int y) { return num[x]<num[y]; } inline void add(int u,int v) { f[++cnt].to=v,f[cnt].next=head[u],head[u]=cnt; } int main() { int i,j,u,v; scanf("%d%d",&n,&m); fo(i,1,m) { scanf("%d%d",&u,&v); add(u,v),du[v]++; } fo(i,1,n) if(!du[i]) q.push(i); while(!q.empty()) { u=q.front(); q.pop(); num[u]=++tot; map[tot]=u; for(i=head[u];i;i=f[i].next) { v=f[i].to; du[v]--; if(!du[v]) q.push(v); } } for(i=n;i;i--) { int top=0; u=map[i]; b[u][u]=1; for(j=head[u];j;j=f[j].next) { v=f[j].to; c[++top]=v; } sort(c+1,c+top+1,comp); fo(j,1,top) { v=c[j]; if(b[u][v]) ans++; else b[u]|=b[v]; } } printf("%d\n",ans); return 0; }
相关文章推荐
- bzoj 4484 [Jsoi2015] 最小表示 solution
- bzoj 4484: [Jsoi2015]最小表示
- BZOJ 4484: [Jsoi2015]最小表示 拓扑排序 bitset
- 【JSOI2015】bzoj4484 最小表示
- bzoj4484[JSOI2015]最小表示
- Bzoj4484 [Jsoi2015]最小表示
- 【bzoj4484】【JSOI2015】【最小表示】【拓扑排序+bitset】
- BZOJ 4484 [Jsoi2015] 最小表示
- bzoj4484[Jsoi2015]最小表示 拓补排序+bitset
- bzoj 4484: [Jsoi2015]最小表示 拓扑排序+bitset
- 4484: [Jsoi2015]最小表示
- 4484: [Jsoi2015]最小表示
- 4484: [Jsoi2015]最小表示 bitset+拓扑序
- 无根树的同构:Hash最小表示法(bzoj 4337: BJOI2015 树的同构)
- [BZOJ4337][BJOI2015]树的同构(树的最小表示法)
- [JSOI2015]最小表示
- BZOJ4484 JSOI2015最小表示(拓扑排序+bitset)
- 【BZOJ1016】【JSOI2008】最小生成树计数
- BZOJ 1016 [JSOI2008]最小生成树计数
- BZOJ 1821 [JSOI2010]Group部落划分 - 最小生成树