HDOJ 4635 - Strongly connected/2013多校联合第四场D Tarjan求强联通图.缩点.
2013-08-07 10:48
651 查看
题意:
给一个有向的简单图(无重复边,无自环)...问该图是否是强连通图..若不是强联通问最多可以加多少条边..使得图依然不是强联通图并且还是简单图...
题解:
首先用tarjan求强联通..判断整个图是否是一个强联通图....如果不是强联通..又要加尽可能多的边保持不强联通..有个方向是选出一块点集x作为独立的..这一块是个完全图..其他点集y也是一个完全图..整个图变成两个完全图..并且x每个点到y每个点都有单向边..保证了不强联通..那写出计算式..最后这个图的边数为:
x*(x-1) + y*(y-1) +x*y = x^2+y^2+x*y-n = n^2-x*y+n
可见..要使得边数最多..x*y就要最小..x*y最小就要使得x与y的差距最大..所以就得出了要找一个点集最小的强联通块作为x..其他的点作为y...计算答案..但要注意..这个x必须是入度或者出度为0的点..否则就会出现y做完全图后导致整个图变成完全图了..也就是整个图强联通了...
Program:
给一个有向的简单图(无重复边,无自环)...问该图是否是强连通图..若不是强联通问最多可以加多少条边..使得图依然不是强联通图并且还是简单图...
题解:
首先用tarjan求强联通..判断整个图是否是一个强联通图....如果不是强联通..又要加尽可能多的边保持不强联通..有个方向是选出一块点集x作为独立的..这一块是个完全图..其他点集y也是一个完全图..整个图变成两个完全图..并且x每个点到y每个点都有单向边..保证了不强联通..那写出计算式..最后这个图的边数为:
x*(x-1) + y*(y-1) +x*y = x^2+y^2+x*y-n = n^2-x*y+n
可见..要使得边数最多..x*y就要最小..x*y最小就要使得x与y的差距最大..所以就得出了要找一个点集最小的强联通块作为x..其他的点作为y...计算答案..但要注意..这个x必须是入度或者出度为0的点..否则就会出现y做完全图后导致整个图变成完全图了..也就是整个图强联通了...
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<cmath> #include<queue> #include<stack> #include<set> #include<map> #include<algorithm> #define ll long long #define eps 1e-5 #define oo 1000000007 #define pi acos(-1.0) #define MAXN 100005 using namespace std; struct node { int x,y,next; }line[MAXN]; int Lnum,_next[MAXN],dfn[MAXN],low[MAXN],tpnum,tp[MAXN],num[MAXN],DfsIndex; bool In[MAXN],Out[MAXN]; bool instack[MAXN]; stack<int> mystack; void addline(int x,int y) { line[++Lnum].next=_next[x],_next[x]=Lnum; line[Lnum].x=x,line[Lnum].y=y; } void tarjan(int x) { int y,k; dfn[x]=low[x]=++DfsIndex; instack[x]=true; mystack.push(x); for (k=_next[x];k;k=line[k].next) { y=line[k].y; if (!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); }else if (instack[y]) low[x]=min(low[x],dfn[y]); } if (low[x]==dfn[x]) { tpnum++; num[tpnum]=0; do { x=mystack.top(); num[tpnum]++; mystack.pop(); tp[x]=tpnum; instack[x]=false; }while (low[x]!=dfn[x]); } return; } int main() { int cases,i,n,m,T; scanf("%d",&T); for (cases=1;cases<=T;cases++) { scanf("%d%d",&n,&m); memset(_next,0,sizeof(_next)); Lnum=0; for (i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); addline(x,y); } memset(dfn,0,sizeof(dfn)); memset(instack,false,sizeof(instack)); while (!mystack.empty()) mystack.pop(); tpnum=DfsIndex=0; for (i=1;i<=n;i++) if (!dfn[i]) tarjan(i); printf("Case %d: ",cases); if (tpnum==1) { printf("-1\n"); continue; } memset(In,true,sizeof(In)); memset(Out,true,sizeof(Out)); for (i=1;i<=m;i++) { int x=tp[line[i].x],y=tp[line[i].y]; if (x==y) continue; Out[x]=false,In[y]=false; } ll x=oo,y; for (i=1;i<=tpnum;i++) if ((Out[i] || In[i]) && x>num[i]) x=num[i]; y=n-x; printf("%I64d\n",x*y+x*(x-1)+y*(y-1)-m); } return 0; }
相关文章推荐
- HDOJ 1827 - Summer Holiday 简单的tarjan求强联通分量+缩点
- HDOJ 3861 - The King’s Problem tarjan求强联通分量&缩点&有向图最小路径覆盖(匈牙利)
- hdoj 1827 Summer Holiday 强联通缩点
- HDU 6165 FFF at Valentine (tarjan缩点+拓扑判任意两点联通)
- 【强联通分量缩点】【Tarjan】bzoj1051 [HAOI2006]受欢迎的牛
- hdoj 1827 Summer Holiday 【有向图 连通最少的点来间接连通所有点】 【tarjan求 SCC + 缩点】
- [HDOJ4635]Strongly connected(强连通分量,缩点)
- poj3177 tarjan双联通缩点
- 2018年全国多校算法寒假训练营练习比赛(第四场) E.通知小弟(Tarjan,缩点)
- HDU/HDOJ 3875 Euclidean Algorithm 多校联合第四场
- HDOJ 4612 - Warm up tarjan求无向图双联通分量+树形DP+stack申请更多空间
- HDOJ 4632 - Palindrome subsequence/2013多校联合第四场A 区间DP
- bzoj 1179 [Apio2009]Atm tarjan强联通缩点+SPFA
- HDU 4635 多校第四场 1004 强联通
- [HDOJ6165] FFF at Valentine(强联通分量,缩点,拓扑排序)
- 2013 杭电多校联合赛 第四场D题 4635 Strongly connected
- HDOJ 题目4612Warm up(双联通求桥数,缩点求树的直径)
- hdoj 3836 Equivalent Sets 【tarjan 求SCC + 缩点】
- HDU 4635 多校第四场 1004 强联通
- lightoj 1168 tarjan 强联通分量加缩点 加各种题目坑