hdu 4635 Tarjan縮點 添邊

2021-09-11 20:03:50 字數 1402 閱讀 3949

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...