點此看題
考慮這個條件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...