[題目鏈結]
[演算法]
記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))
[**]
#includeusingnamespace
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的指數差...