SDOI2016 數字配對

2021-10-01 10:51:17 字數 2057 閱讀 9474

點此看題

考慮這個條件ai是aj的倍數,且ai/aj是乙個質數,滿足這個條件就必須要滿足下面兩個條件:

第二個條件很重要,它告訴我們可以把數字的cnt

cntcn

t奇偶劃分,就能得到乙個二分圖,我們就可以想網路流的方面想,圖是這樣建的:

然後我們在建好的圖上跑費用流,由於圖是二分圖,最長路一定是單調遞減的,於是跑費用流是判斷費用用大於0

00,這裡的費用流寫法不同,應寫成最大費用最大流。

#include

#include

#include

#include

#include

#define int long long

#define inf (1ll<<60)

const

int maxn =

205;

using

namespace std;

intread()

int n,tot,s,t,f[maxn]

,a[maxn]

,b[maxn]

,c[maxn]

;int flow[maxn]

,dis[maxn]

,pre[maxn]

,lst[maxn]

;struct edge

e[maxn*maxn]

;struct node};

vector a,b;

void

add_edge

(int u,

int v,

int c,

int fl)

,f[u]

=tot;

e[++tot]

=edge

,f[v]

=tot;

}int

dec(

int x)

if(x!=

1) cnt++

;return cnt;

}boolpd(

int x,

int y)

bool

bfs())

;while

(!q.

empty()

));}

}}return dis[t]

!=-inf;

}int

get()}

else

return sum+cost/

(-dis[t]);

}return sum;

}signed

main()

);else

b.push_back

(node);

}for

(int i=

1;i<=n;i++

) b[i]

=read()

;for

(int i=

1;i<=n;i++

) c[i]

=read()

;for

(int i=

0;isize()

;i++

)add_edge

(s,a[i]

.u,0

,b[a[i]

.u])

;for

(int i=

0;isize()

;i++

)add_edge

(b[i]

.u,t,

0,b[b[i]

.u])

;for

(int i=

0;isize()

;i++

)for

(int j=

0;jsize()

;j++)if

(pd(a[i]

.c,b[j]

.c))

add_edge

(a[i]

.u,b[j]

.u,c[a[i]

.u]*c[b[j]

.u],inf)

;printf

("%lld\n"

,get()

);}

SDOI2016 數字配對

傳送門 裸費用流。建邊 對於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 流量無窮大...

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