CodeForces 732 F.Tourist Reform(边双连通分量)
来源:互联网 发布:java 请求跨域转发 编辑:程序博客网 时间:2024/06/14 22:14
Description
给出一个n个点m条边的图,现在要给每条边定向,定向后定义r[i]为顶点i可达的点数,要求最大化r[i]的最小值
Input
第一行两个整数n和m分别表示点数和边数,之后m行每行输入两个整数u和v表示u和v之间有一条边(2<=n<=4e5,1<=m<=4e5)
Output
输出最大化后的r[i]最小值,然后输出定向后的每条边
Sample Input
7 9
4 3
2 6
7 1
4 1
7 3
3 5
7 4
6 5
2 5
Sample Output
4
4 3
6 2
7 1
1 4
3 7
5 3
7 4
5 6
2 5
Solution
求出边双连通分量后,每个边双连通分量后,同一个块内点的r[i]值一样,为使得r[i]的最小值最大,那么每个块都要向块内点数最大的那个块连边,这样答案就是最大块的点数
Code
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>#include<set>#include<ctime>using namespace std;typedef long long ll;#define INF 0x3f3f3f3f#define maxn 444444 typedef pair<int,int>P;vector<P>G[maxn];int low[maxn],dfn[maxn],stack[maxn],belong[maxn],flag[maxn];//belong数组的值是1~blockint index,top;int block;//边双连通块数bool instack[maxn];int bridge;//桥的数目int n,m,num;int vis[maxn];//标记点int mark[maxn];//标记边 P edge[maxn];void addedge(int u,int v,int id){ G[u].push_back(P(v,id)); G[v].push_back(P(u,id));}void Tarjan(int u,int pre){ int v,id; low[u]=dfn[u]=++index; stack[top++]=u; instack[u]=1; for(int i=0;i<G[u].size();i++) { v=G[u][i].first,id=G[u][i].second; if(v==pre)continue; if(!dfn[v]) { Tarjan(v,u); if(low[u]>low[v])low[u]=low[v]; if(low[v]>dfn[u]) { bridge++; flag[id]=1; } } else if(instack[v]&&low[u]>dfn[v]) low[u]=dfn[v]; } if(low[u]==dfn[u]) { block++; do { v=stack[--top]; instack[v]=0; belong[v]=block; } while(v!=u); }}void init(int n){ index=0; for(int i=1;i<=n;i++)G[i].clear(); memset(flag,0,sizeof(flag)); memset(vis,0,sizeof(vis)); memset(mark,0,sizeof(mark));}void dfs1(int u){ if(!vis[u])num++; vis[u]=1; for(int i=0;i<G[u].size();i++) { int v=G[u][i].first,id=G[u][i].second; if(flag[id]||mark[id])continue; mark[id]=1; edge[id]=P(u,v); dfs1(v); }}void dfs2(int u){ for(int i=0;i<G[u].size();i++) { int v=G[u][i].first,id=G[u][i].second; if(mark[id])continue; mark[id]=1; if(flag[id])edge[id]=P(v,u); dfs2(v); }}int main(){ while(~scanf("%d%d",&n,&m)) { init(n); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); addedge(u,v,i); edge[i]=P(u,v); } Tarjan(1,1); int ans=0,pos=-1; for(int i=1;i<=n;i++) if(!vis[i]) { num=0; dfs1(i); if(num>ans)ans=num,pos=i; } memset(mark,0,sizeof(mark)); dfs2(pos); printf("%d\n",ans); for(int i=1;i<=m;i++)printf("%d %d\n",edge[i].first,edge[i].second); } return 0;}
0 0
- CodeForces 732 F.Tourist Reform(边双连通分量)
- codeforces round 377 div2 F Tourist Reform tarjan求边双连通分量
- codeforces732F Tourist Reform(边双连通分量)
- CodeForces 732F Tourist Reform
- codeforces 732F Tourist Reform
- CODEFORCES 732F Tourist Reform
- 【CF 732F】 Tourist Reform(割边+dfs)
- [CF 732F]Tourist Reform
- Codeforces 732F Tourist Reform【思维+边双联通+Dfs处理后继问题】好题!
- 边双连通分量
- hdu 2242(边双连通分量)
- uva 10972(边双连通分量)
- UVA 10972(边双连通分量)
- poj3352Road Construction(边双连通分量)
- 双连通分量(点+边)
- 点-双连通分量&边-双连通分量复习笔记
- 边双连通分量模版
- HDU4738【边双连通分量】
- DHCP动态主机配置协议
- Java Socket实战之七 使用Socket通信传输文件
- 基于 Django1.10 文档的深入学习(30)——Class-based views
- 信息加密2
- 2.网络IO
- CodeForces 732 F.Tourist Reform(边双连通分量)
- solr集群步骤
- 前缀树(字典树)Trie的c代码
- JavaSE 学习参考:反射机制(2)Field类
- 【java】最小生成树(Prim算法,Kruskal算法)
- Java Socket实战之八
- 工作流学习——Activiti流程实例、任务管理四步曲
- 1054. 求平均值
- GDOI2017游记