題意:
給你n個人,m條年齡大小的關係,現在打算把這些人分成不同的集合,使得每個集合的任意兩個人之間的年齡是不可比的。問你最小的集合數是多少?
分析:首先,假設有乙個環,那麼這個環中的任意兩個點之間都是可比的,並且,和這個環相連的任意乙個點或環也和這個環是可比的,因為關係具有傳遞性。但如果兩個點或者環,無法處在同一條路徑上,那麼這兩個點和環就是不可比的。所以,如果我們把這些環--強連通分量縮為乙個點。強連通分量的點數就是縮點後的點權。那麼縮點後的新圖就是乙個有向帶權無環圖,題目就是要求我們求出這個有向帶權無環圖的關鍵路徑----最長路徑。(因為那些較短的路徑上的點總可以和較長的路徑點和為一點)。
1//first edit time: 2014-11-25 13:382//
last edit time: 2014-11-25 14:24
3 #include4 #include5 #include6
using
namespace
std;78
#define _clr(x, y) memset(x, y, sizeof (x))
9#define min(x, y) (x < y ? x : y)
10#define max(x, y) (x > y ? x : y)
11#define inf 0x3f3f3f3f
12#define n 100010
1314 vectormap[n], new_map[n];
15int
low[n], dfn[n];
16int
stack[n], be[n];
17bool
instack[n];
18int
dist[n], sum[n];
19int
top, n, cnt, time;
2021
void
init()
2236}37
38//
dfs生成樹求強連通分量
39void dfs(int
u)40
52else
if(instack[v])
53 low[u] =min(low[u], dfn[v]);54}
55if(dfn[u]==low[u])
56while(dfn[u] !=low[u]);65}
66}6768
void
tarjan_scc()
6975
for(int i=1; i<=n; i++)
7683}84
}8586int get(int
u)87
9495
intmain()
96106
107 tarjan_scc(); //
tarjan演算法求強連通縮點為乙個dag
108109
int ans = -inf;
110for(int i=1; i<=cnt; i++) //
記憶化搜尋求dag關鍵路徑
111 ans =max(get(i), ans);
112113 printf("
%d\n
", ans);
114}
115return0;
116 }
模板 強連通縮點
直接給他縮點然後求新的圖的完整版 c2 u 表示縮點後的u點這個環上的點實際上是哪些 g3 u 表示縮點後的u點的出邊 還是一樣,要記得先處理入鏈。可以讓這個圖好看一點但是沒啥鳥用 入鏈可能會有一些特別的性質,當然假如入鏈沒有特別性質也可以直接縮點。不對其實直接縮點就可以了,入鏈還是新圖的入鏈,環是...
hdu 2767 強連通縮點
補最少的邊成強連通圖。縮點後成dag,max即為所求。include include include define mn 20020 define me 200010 define mm a,b as void add e int i,int u,int v void tarjan int i el...
hdu 4635 強連通縮點
多校聯賽4的一道題,給乙個有向圖,問最多加多少條邊後仍然不是強聯通,以前總會遇到問最少加幾條邊讓圖成乙個強連通圖,比賽時自己就找到了答案,當時想著新增最多的邊後一定是將原來的圖連成兩個強連通分量,而兩個強連通分量間的邊最多是兩個聯通分量的點數之積,再加上每個聯通分量內部的點的邊數就是所有的邊數,再減...