SDOI2016 數字配對

2021-09-28 18:15:29 字數 1812 閱讀 5073

傳送門

裸費用流。

建邊:對於a[i

]a[j

]=pr

ime&

a[j]

∣a[i

]\frac=prime \& a[j]|a[i]

a[j]a[

i]​=

prim

e&a[

j]∣a

[i],需要i

ii向j+n

j+nj+

n連,並且j

jj向i+n

i+ni+

n連。費用即為c[i

]∗c[

j]

c[i]*c[j]

c[i]∗c

[j],流量無窮大。而源點向左側每個點連邊,費用為0,流量為b[i

]b[i]

b[i]

,右側向匯點也如此。可以發現,這樣相當於是每一種數的個數翻了一倍,所以最後答案除以2即可。

費用流就是每次按照費用找到一條最短路然後增廣。

那麼如果當前增廣後的費用小於了0,那麼就不流滿,增加流量至費用剛好大等於0。否則可以全部流滿。由於總費用是和0作比較,那麼就不存在除以2的問題。

#include

#define cs const

#define re register

#define ll long long

cs int n=

205,m=

162000

,oo=

1e9;

cs ll oo=

1e18

;int n,key[n]

,num[n]

,s,t;ll val[n]

;namespace io

template

<

typename t>

inline t get()

while

(isdigit

(ch)

) x=

((x+

(x<<2)

)<<1)

+(ch^48)

,ch=gc(

);return x*f;

}inline

intgi()

inline ll gl()

}using io::gi;

using io::gl;

namespace math}}

inline

bool

isprime

(int x)

}using math::isprime;

inline

void

min(

int&x,

int y)

namespace flow

inline

bool

spfa()

}}return dis[t]

!=-oo;

}inline

intmcf

(int ans_flow=

0,ll ans_cost=0)

ans_flow+

=flow[t]

,ans_cost+

=dis[t]

*flow[t]

;for

(int re u=t;u!=s;u=pre[u]

) w[edge[u]]-

=flow[t]

,w[edge[u]^1

]+=flow[t];}

return ans_flow/2;

}}using flow::add;

intmain()

SDOI2016 數字配對

點此看題 考慮這個條件ai是aj的倍數,且ai aj是乙個質數,滿足這個條件就必須要滿足下面兩個條件 第二個條件很重要,它告訴我們可以把數字的cnt cntcn t奇偶劃分,就能得到乙個二分圖,我們就可以想網路流的方面想,圖是這樣建的 然後我們在建好的圖上跑費用流,由於圖是二分圖,最長路一定是單調遞...

SDOI 2016 數字配對

戳一戳 感覺自己調了半天然後模板打錯了。好難過。rsduheiutfhnesrfnsjkenfkj 不bibi了我們講一下如何建圖。我們可以發現這2個數字之間的關係是雙向的。那我們怎麼辦呢 手動滑稽 這裡有乙個很神奇的結論 如果a為b的因數且b除以a的值為質數,那麼將a與b質因數分解後a與b的指數差...

SDOI 2016 數字配對

題目鏈結 演算法 記cnti表示第i個數的質因子次數之和 那麼i與j可以配對當且僅當 cnti cntj 1且ai為aj的倍數或cntj cnti 1且aj為ai的倍數 那麼cnti為奇數與cnti為偶數的點構成了兩個集合 考慮費用流 將源點與cnti為奇數的點連一條容量為bi 費用為0的邊 將cn...