HDU 2767 至少添加都是边成强连通图
来源:互联网 发布:淘宝定制机箱有哪里家 编辑:程序博客网 时间:2024/05/23 13:21
题目大意:给定一张有向图,问最少添加几条边使得有向图成为一个强连通图。
跑一边tarjan,如果是联通的就输入0,没有边要加的 , 顺便把图缩点 ;(这类题本博客做过,直接把以前思路贴上来)
要使缩点后的图成为强连通图,每个顶点最少要有一个入度(其他点连接它)和一个出度(它连接其他点),一条边又提供一个出度和一个入度。
所以可以通过统计没有入度的顶点数 noInDegree 和 没有出度的顶点数 noOutDegree。即对于每个缩点,少出度就添,少入度就添;
所需要添加的边数就是noInDegree和noOutDegree中的最大值。
#include<cstdio>#include<cstring>#include<map>#include<vector>#include<cmath>#include<cstdlib>#include<queue>#include <iomanip>#include<iostream>#include<algorithm>using namespace std ;const int N=30000 ;const int M=55000 ;struct node{int u,v,next ;}edge[M] ;int head[N] ,low[N],dnf[N],stack[N],vis[N] ,belong[N];int in[N],to[N] ;int top ,cnt,dep,sum;void add(int u,int v){edge[top].u=u;edge[top].v=v;edge[top].next=head[u] ;head[u]=top++;}void tarjan(int u){int x ;low[u]=dnf[u]=++dep ;stack[cnt++]=u ;vis[u]=1 ;for(int i=head[u] ;i!=-1;i=edge[i].next){ int v=edge[i].v ; if(!dnf[v]) { tarjan(v) ; low[u] = min(low[u],low[v]) ; }else if(vis[v]) low[u] = min(low[u],dnf[v]) ;}if(low[u]==dnf[u]){ sum++ ; do { x=stack[--cnt] ; belong[x] =sum ; vis[x]=0; }while(x!=u) ;}}int main(){ int t,n,m,a,b; scanf("%d",&t) ; while(t--) { top = 0 ; cnt=dep=sum = 0 ; memset(head,-1,sizeof(head)) ; memset(low,0,sizeof(low)) ; memset(dnf,0,sizeof(dnf)) ; memset(vis,0,sizeof(vis)) ; memset(in,0,sizeof(in)) ; memset(to,0,sizeof(to)) ; scanf("%d%d",&n,&m) ; if(m==0) printf("%d\n",n) ; else{ for(int i = 0 ; i < m ; i++) { scanf("%d%d",&a,&b) ; add(a,b) ; } for(int i = 1 ; i <= n ; i++) { if(!dnf[i]) tarjan(i) ; } for(int i = 1 ; i <= n ; i++) for(int j=head[i] ;j!=-1;j=edge[j].next) { int v= edge[j].v ; if(belong[i]!=belong[v]) { in[belong[v]]++ ; to[belong[i]]++; } } if(sum <= 1 ) printf("0\n") ; else { int sum1=0,sum2=0; for(int i = 1 ; i <= sum ; i++) { if(!in[i]) sum1++; if(!to[i]) sum2++ ; } printf("%d\n",max(sum1,sum2)) ; } } } return 0;}
0 0
- HDU 2767 至少添加都是边成强连通图
- HDU 2767 Proving Equivalences (HDU 3836) 至少加几条边让整个图变成强连通+邻接表建图
- hdu 2767 Proving Equivalences(至少加几条边让整个图变成强连通)
- Tarjan算法求至少要添加几条边才能使无向连通图变为边双连通图。
- hdu3836 Equivalent Sets(有向图至少添加多少条边才能变为强连通图+tarjan缩点)
- Tarjan算法求至少要添加几条边才能使无向连通图变为边双连通图。
- 2767 Proving Equivalences 至少加几条边让全部图变成强连通模板题
- hdu 2767 (加边构强连通)
- HDU 5438--连通图
- HDU2767Proving Equivalences(强连通+缩点+ 至少加几条边让整个图变成强连通))
- hdu 2767(强连通分量)
- HDU 2767 强连通分量
- hdu 2767强连通分量
- hdu3836 Equivalent Sets (至少加几条边让整个图变成强连通&hdu2767)
- 无向连通图至少增加多少边形成双联通
- hdu 2767 Proving Equivalences(强连通分量)
- 周赛 HDU 2767 1269 1872 强连通
- HDU 2767 强连通之缩点
- sgu 176 Flow construction(有源汇上下界最小流)
- mysql字符串截取
- Linux——进程的控制 信号
- 鼠标画图
- linux内核数据库sqlite3的移植和简单操作
- HDU 2767 至少添加都是边成强连通图
- 并查集 + Bfs 之 zoj 3811 Untrusted Patrol
- 本办法学python 随记2
- 查询数据库中某字段中包含某值的方法
- snmp trap发送及接收
- Deruio制作 树莓派用户手册V001
- PE文件重定位
- S5PC100的时钟机制
- 使用CSS居中表(二)