SDOI 2016 數字配對

2022-05-04 23:30:10 字數 1906 閱讀 3091

[題目鏈結]

[演算法]

記cnti表示第i個數的質因子次數之和

那麼i與j可以配對當且僅當 : cnti = cntj + 1且ai為aj的倍數或cntj = cnti + 1且aj為ai的倍數

那麼cnti為奇數與cnti為偶數的點構成了兩個集合

考慮費用流 :

將源點與cnti為奇數的點連一條容量為bi , 費用為0的邊

將cnti為偶數的點向匯點連一條容量為bi , 費用為0的邊

對於所有可以配對的(i , j) , 將i與j連一條容量為正無窮 , 費用為cicj的邊

答案即為這張圖的最大費用最大流

但注意由於題目中要求費用為非負數 , 所以可以考慮貪心 :

由於最大費用最大流每次找到的增廣路的費用單調遞減 , 所以優先考慮費用大的

時間複雜度 : o(costflow(n , n ^ 2))

[**]

#includeusing

namespace

std;

#define n 520typedef

long

long

ll;typedef

long

double

ld;typedef unsigned

long

long

ull;

const ll inf =1e18;

struct

edge

e[n * n * 4

];int

n , tot , s , t;

ll sum , ans;

inta[n] , b[n] , c[n] , cnt[n] , pre[n] , head[n];

ll dist[n] , incf[n];

bool

inq[n];

template

inline void chkmax(t &x,t y)

template

inline void chkmin(t &x,t y)

template

inline void read(t &x)

inline

void addedge(int u , int

v , ll w , ll cost)

; head[u] =tot;

++tot;

e[tot] = (edge);

head[v] =tot;

}inline

intget(int

x) }

if (x > 1) ++ret;

return

ret;

}inline

bool

spfa()

pre[s] = 0

; inq[s] = true

; dist[s] = 0

; incf[s] =inf;

q.push(s);

while (!q.empty())}}

}if (dist[t] != -inf) return

true

;

else

return

false;}

inline

bool

update()

return

true

; }

else

}int

main()

}

}while (spfa() &&update());

printf(

"%lld\n

", ans);

return0;

}

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 流量無窮大...

SDOI2016 數字配對

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

SDOI 2016 數字配對

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