最多不相交路徑

2021-08-31 17:27:39 字數 1280 閱讀 4846

最長上公升子串行是乙個經典問題,可以用o(n^2)的dp解決。給出乙個串,求出最長上公升子串行的長度為多少?假設長度為s,現在問題是,有多少個長度為s的上公升子串行,滿足每個子串行所包含的元素均不相同(即乙個數只能選一次)。

建模:第一問直接用dp求解,dp[i]表示以i為結尾的最長遞增子串行的長度,最後取dp[1~n]的最大值,即為s。

第二問可以利用上一問求出來的dp陣列,用網路流求解。

1. 拆點,將每個點拆成兩點,容量為1,保證每個點只取一次。

2. 增加源點s和匯點t,s和dp[i]=1的點相連,dp[i]=s的點和t相連,容量均為inf。

3. 對於兩點i和j(j

這樣,保證從s到t的每一條路都是一條最長遞增子串行,最大流即為答案。

例:hdu3998

#include #include #include using namespace std;

const int inf = 0x7fffffff;

const int maxv = 2000;

const int maxe = maxv*maxv*2;

int n,s;

int a[maxv];

int dp[maxv];

int source,sink;

//struct edge

;edge e[maxe];

int head[maxv],edgenum;

int now[maxv],d[maxv],vh[maxv],pre[maxv],preh[maxv];

void addedge(int a,int b,int c)

void init()

int sap(int s,int t,int n) //源點,匯點,結點總數

while(x!=s);}}

else

}++vh[d[x]];

if(x != s)

x = pre[x];}}

return ans;}//

void build()

for(i = 1; i <= n; i++)

}}int main()

}for(i = 1; i <= n; i++)

printf("%d\n",s);

build();

printf("%d\n",sap(source,sink,sink+1));

}return 0;

}

選擇不相交區間

思路 為什麼要這樣做呢 首先分析一下題意,就是選擇盡量多的不相交區間,那麼我們就要去掉一些區間,使剩下 的區間不相交,那麼我們要去掉什麼樣的區間呢?我們假設區間 a1,b1 a2,b2 1,如果a1b2,我們說區間1包含區間2,那麼我們就要去掉區間1 2,如果a1 a2 b1 b2,這時候我們仍然要...

不相交集ADT

1.不相交集是解決等價關係的一種資料結構,執行合併和查詢的速度都非常快,m次執行合併和查詢的執行時間為 m logn 在乙個集合中,對於每一對元素 a,b a,b s,對於關係r如果滿足下面三個條件,則成關係r為等價關係 1 自反性 對於所有a s,ara 2 對稱性 arb當且僅當bra 3 傳遞...

不相交集ADT

首先我們必須明白不相交集這種資料結構是用來幹什麼的。不相交即主要用來實現動態等價問題的求解。動態 等價問題 這裡不再說明等價關係的概念,這個可以參考數理邏輯之類的書。假設我們有乙個集合和乙個等價關係 針對集合中的任意兩個元素 a 和 b,我們如何確定他們有等價關係 即a b.那麼我們需要等價類的概念...