codeforces 732F 双联通分量
来源:互联网 发布:小米note 顶配版我知乎 编辑:程序博客网 时间:2024/06/06 21:02
点击打开链接
题意:给一个无向图,现在将所有的边变为有向,使得每个点可以到达的点的个数的最小值最大,然后将变好的有向图输出
思路:可以知道无向图时在一个连通分量中的点是可以做到互达的,也就是这个联通分量里的点可以变成有向的联通分量,那么现在的图就是一个由好多个连通分量组成的一个树,然后对于割边来说,只有确定它的方向才能找出那个最小值,因为割边为有向了,所以所有的联通块肯定都是指向最大的那个联通块才能达到要求,画个图看一下即可,然后剩下的工作就是将无向的联通块的边变为有向,用一个dfs搜一下就行了
#include <queue>#include <vector>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <iostream>#include <algorithm>using namespace std;typedef long long ll;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const ll INF=0x3f3f3f3f3f3f3f3fll;const int maxn=400010;struct edge{ int to,flag,rev,id; edge(int a,int b,int c,int d){to=a;flag=b;rev=c;id=d;}};vector<edge>G[maxn];int L[maxn],E[maxn],vis[maxn],stack1[maxn];int n,m,k,kk;void dfs(int x,int fa){ vis[x]=1;L[x]=k;E[x]=k++;stack1[kk++]=x; int flag=0; for(unsigned int i=0;i<G[x].size();i++){ edge e=G[x][i]; if(e.to!=fa){ if(!vis[e.to]){ dfs(e.to,x); L[x]=min(L[x],L[e.to]); }else L[x]=min(L[x],E[e.to]); }else{ if(flag) L[x]=min(L[x],E[e.to]); flag++; } } if(L[x]==E[x]){ while(stack1[kk]!=x&&kk>0){ L[stack1[kk-1]]=L[x]; kk--; vis[stack1[kk]]=0; } }}void tarjan(){ memset(L,0,sizeof(L)); memset(E,0,sizeof(E)); memset(stack1,0,sizeof(stack1)); kk=0;k=1;dfs(1,1);}int U[maxn],V[maxn],val[maxn],fans[maxn][2];void fdfs(int x,int fa){ for(unsigned int i=0;i<G[x].size();i++){ edge t=G[x][i]; if(t.flag||t.to==fa) continue; G[t.to][t.rev].flag=1; G[x][i].flag=1; if(L[x]!=L[t.to]){ fans[t.id][0]=t.to,fans[t.id][1]=x; fdfs(t.to,x); }else{ fans[t.id][0]=x;fans[t.id][1]=t.to; fdfs(t.to,x); } }}int main(){ while(scanf("%d%d",&n,&m)!=-1){ for(int i=0;i<=n;i++){ G[i].clear();vis[i]=0;val[i]=0; } for(int i=1;i<=m;i++){ scanf("%d%d",&U[i],&V[i]); G[U[i]].push_back(edge(V[i],0,G[V[i]].size(),i)); G[V[i]].push_back(edge(U[i],0,G[U[i]].size()-1,i)); } tarjan(); for(int i=1;i<=n;i++) val[L[i]]++; int max1=0,fpos; for(int i=1;i<=n;i++) if(val[i]>max1) max1=val[i],fpos=i; printf("%d\n",max1); for(int i=1;i<=n;i++) if(L[i]==fpos){fdfs(i,0);break;} for(int i=1;i<=m;i++) printf("%d %d\n",fans[i][0],fans[i][1]); } return 0;}
0 0
- codeforces 732F 双联通分量
- 浅谈强联通分量,双联通分量
- CodeForces 231E|Cactus|边双联通分量|LCA
- 双联通分量
- 边双联通分量
- 边双联通分量
- 点双联通分量
- 边双联通分量
- 双联通分量 HDU4738
- Codeforces 732F Tourist Reform【思维+边双联通+Dfs处理后继问题】好题!
- UVALive5796点双联通分量or边双联通分量
- 点双联通分量和边双联通分量小结
- POJ 3177(双联通分量)
- poj3694(边双联通分量)
- HDU 4738 双联通分量
- POJ 1515 双联通分量
- 边双联通分量poj3352
- POJ3177Redundant Paths (双联通分量)
- SQL Server 2012 自动增长列,值跳跃问题
- iOS 模糊搜索的实现
- Javascript模块化编程(一):模块的写法
- java获取本周的周一到和周天
- 微信公众号开发(1)
- codeforces 732F 双联通分量
- nginx rewrite 指令
- 系统中的DEP功能
- html中 让 ul 的多个 li 在一行内显示
- 关于绝对路径和相对路径(啥啥未定义或者找不到神码目录)
- Quartz整理
- (转)美国进入智能投顾竞争时代
- Spring MVC入门
- Javascript模块化编程(二):AMD规范