n個點m條邊的有向圖,在保證不是強連通圖的情況下最多可以新增多少條邊。1 <= n <= 1e5 ,1 <= m <= 1e5。
1.正向思考不容易想到,逆向思考,把該有向圖變成完全圖,即n*(n-1)條邊,在不減少原有的m條邊內的邊的條件下最多可以減少多少條邊。最後得到乙個有兩個強連通分量的圖,記作x和y,x分量有x個點,y分量有y個點,x分量是完全子圖,y分量是完全子圖,x分量的每個點都有指向y分量的每個點的邊。可新增x*(x-1) + y*(y-1) + x*y - m = n*(n-1) - x * y - m條邊。盡量使x * y小,即盡量使abs(x - y)大。
2.tarjan縮點,記錄每個強連通分量的點的個數。然後找到最小的分量點數num,答案為n*(n-1) - num * (n - num) - m。
#include#define n 100005
#define inf 0x3f3f3f3f
using namespace std ;
struct edge
edge[n] ;
int head[n] ;
int vis[n] , dfn[n] , low[n] , s[n] ;
int id[n] , in[n] , out[n] ;
long long scc[n] ;
int scc_num , bridge_num ;
int top1 , lay , cnt ;
long long n , m ;
void init()
void addedge(int u , int v)
void tarjan(int u)
} if(dfn[u] == low[u])
scc[scc_num] ++ ;
id[s[top1]] = scc_num ;
vis[s[top1]] = 2 ;
top1 -- ; }}
void find()
}}long long cal()
ans = n * (n - 1) - num * (n - num) - m ;
return ans ;
}int main()
for(i = 1 ; i <= n ; i ++)
if(vis[i] == 0)
tarjan(i) ; //縮點
find() ; // 找入度為0的點和出度為0的點
ans = cal() ; // 計算答案
if(scc_num == 1)
ans = -1 ;
printf("case %d: %lld\n" , ++case_num , ans) ;
}}
Tarjan縮點 SPFA 縮點
洛谷p3387縮點 tarjan spfa求dag上單源最短路模板題 用tarjan在原圖上求scc 縮點 用縮點之後的scc建乙個有向無環圖 scc權為此scc內所有點點權和 在新建的dag上將scc權視為邊權跑spfa 求scc 1 到scc n 的最長路即為所求答案 include inclu...
Tarjan演算法 縮點
我們這一篇是在已經了解tarjan演算法的基礎之上開始寫的,如果不了解的話,請先看大牛們 關於tarjan演算法的部落格。首先我們對於乙個有向無環的圖 dag 至少新增幾條邊才能使它變為強連通圖?我們很容易根據有向無環圖的性質得到,我們計算入度為零的點數為a,出度為零的點數為b,那麼我們至少需要新增...
Tarjan 縮點 模板
縮點以後,整張圖變為dag 有向無環圖 此時運用拓撲排序 求出度入度就可以完成許多事 題目 include include include include include include define ll long long using namespace std const int maxn 1...