练习了一下网络流
一共16题吧,刚刚入门,网络流主要练习了最大流与最小割,网络流一些题与二分图很相似,也要用到二分图的一些性质,一般是只有两个对象的时候,或者可以将一个点拆成两个点时。
小技巧:
dinic最后一次bfs的d数组正好可以用来判断 被选到的点。如果d[]有值 说明被选了 如果没有值就说明没有选
拆点作用:①得这个点只走一次 ②将一个点 转化为 意义不相同的两部分
平面图最小割 = 对偶图最短路
对偶图建图使用的是二维转化一维的方法
补充:
唯一分解定理:
对于任何一个大于1的正整数,都存在一个标准的分解式: N=p1^a1 * p2^a2* ···pn^an;(其中一系列an为指数,pn为质数)
设F(N)代表n的正因子的数量,则F(N)=(a1+1)(a2+1)(a3+1)······*(an+1);
设G(n)代表n的正因子的和,则G(N) =Π ai*(1-q^n)/(1-q)
还学习了
KM算法
模板
int w[N][N];
int la[N],lb[N];
bool visa[N],visb[N];
int match[N];
int delta,upd[N];
bool dfs(int x){
visa[x] = 1;
For(y,1,n){
if(!visb[y]){
if(la[x] + lb[y] - w[x][y] == 0){
visb[y] = 1;
if(!match[y] || dfs(match[y])){
match[y] = x;
return 1;
}
}
else upd[y] = min(upd[y],la[x] + lb[y] - w[x][y]);
}
}
return 0;
}
int KM(){
mst(match,0);
mst(lb,0);
For(i,1,n){
la[i] = w[i][1];
For(j,1,n){
la[i] = max(la[i],w[i][j]);
}
}
For(i,1,n){
fill(upd+1,upd + 1 + n,INF);
while(1){
mst(visb,0);
mst(visa,0);
if(dfs(i)) break;
delta = INF;
For(j,1,n){
if(!visb[j]) delta = min(delta,upd[j]);
}
For(j,1,n){
if(visa[j]) la[j] -= delta;
if(visb[j]) lb[j] += delta;
else upd[j] -= delta;
}
}
}
int res = 0;
For(i,1,n){
res += w[match[i]][i];
}
return res;
}
KM用于求最大权完备匹配
1.如果原图能由多个不相交的有向环覆盖,那么二分图必然存在完备匹配.
2.如果二分图存在完备匹配,那么原图必定能由几个不相交的有向环覆盖.
3.如果原图存在权值最大的有向环覆盖,那么二分图的最优匹配一定就是这个值.
另外,利用一些技巧可以求 最小权完备匹配 边权之积最大