hdu5495 LCS (群論 並查集)

2021-10-03 22:04:34 字數 1772 閱讀 9839

題意:

選擇一種排列,使得陣列a和b有更多的相同子串行。

例如,例1:1 2 3 和 3 2 1 ;p可以為2 1 3;

所以排列為 a2 a1 a3 和 b2 b1 b3.

即 2 1 3 和 2 3 1; 此時 2 1 是相同子串行, 長度為2;

再例如 , 例2:

61 5 3 2 6 4

3 6 2 4 5 1

可以看成

1 3 2 4 5 6

3 2 4 1 6 5

第乙個部分,可以排序得到

1 4 2 3

3 1 4 2

子串行長度為 4 - 1;(如果an != bn 所以每個部分的長度 最長為 每個子串行的長度 - 1, 如果an == bn , 每個部分的長度 最長為 每個子串行的長度, 則 每個an 可以看出乙個部分)

if 部分的長度 == 1, 則 ans ++;

else ans += (部分的長度 - 1);

此時 ans = (4 - 1) + (2 - 1) = 4;

群置換**如下

#include

#include

#include

#include

using

namespace std;

const

int max =

1e5+5;

intmain()

;for

(int i =

1; i <= n; i++

)for

(int i =

1; i <= n; i++

)scanf

("%d"

,&b[i]);

int ans =0;

for(

int i =

1; i <= n; i++)if

(t ==

1) ans++

;else ans +

=(t -1)

;}}printf

("%d\n"

, ans);}

}

其實兩種做法只是找集合的方法不一樣。

並查集的**如下

#include

#include

#include

using

namespace std;

const

int max =

1e5+5;

int a[max]

, b[max]

;int fa[max]

, t[max]

;void

init

(int n)

}int

find

(int x)

void

union

(int x ,

int y)

}int

main()

for(

int i =

0; i < n ; i++

)int ans =0;

for(

int i =

0; i < n ; i++

)else}}

printf

("%d\n"

, ans);}

return0;

}

HDU3938 並查集 並查集

先按邊權值排個序,每次加入一條邊,用並查集,關鍵看懂題。include include include include using namespace std const int maxn 10010 int n,m,q struct edge edges maxn 5 inline int cmp...

hdu 拓撲排序 並查集

題目大意 有一些池塘,每乙個池塘都有乙個價值,現在想刪除一些池塘。有如下刪除條件 1 乙個池塘有兩個管道連線的不可以刪除。2 求最後剩下的為奇數環的池塘的價值。先用拓撲排序的思路將兩個一下連線的全刪除 只有用並查集統計數目 includeusing namespace std define ll l...

hdu 1198 並查集應用

其實可能是因為知道是用並查集做的原因啦,一下就看出題意了,明顯是並查集思想,每次輸入地圖中的一塊,檢測這一塊與它頂頭的那塊可不可以相通 如果可以合併集合 同理檢測其與它左邊的那一塊 最後遍歷一遍看有多少個根結點即要多少個水源 下面是 有點亂 include include define m 55 d...