注:因為風骨傲天習慣用\(dfs+dinic\),所以不會用到\(ek\)等其他形式,而預流推進等較高階的,等我學了再說吧……
事實上,這一部分只會包括最大流和最小費用最大流的略解,後面會補上帶上下界的。
最大流:
inline bool bfs()
return d[t]?1:0;
}inline int dfs(int pos,int dis)
} }return 0;
}inline int dinic()
return ans;
}
費用流:
inline bool bfs()
}return 0;
}int dinic()
return ans;
}
實際上,最小割的應用很多:詳見國家集訓隊胡伯濤**:最小割模型在資訊學中的應用
1.最大權閉合子圖
閉合圖:對於乙個有向圖\(g\),存在點集合\(v\),任取點\(u\)屬於\(v\),\(u\)的出邊的另乙個點也屬於\(v\),則為閉合圖。
最大閉合子圖,即原圖每個點有點權,求原圖的閉合子圖中最大點權和(點權可正可負)。
轉化:\(s\)向所有正權點建邊,容量為點權,所有負權點向\(t\)建邊,容量為點權絕對值,原邊容量為\(inf\)。
最大權\(=\)正權和\(-\)最大流。乙個通俗易懂的證明
變式:\([ceoi2008]order\)
(下附**):將原邊容量改為租金即可(因為租用與否僅和此工序有關)
#includeusing namespace std;
inline int read()
while(x!=eof&&x>='0'&&x<='9')
return w*f;
}const int n=300010;
int n,m,sum,s,t;
int head[n],num_edge,d[n],cur[n];
struct edge[n*10];
inline void add(int from,int to,int dis)
inline bool bfs()
return d[t]?1:0;
}inline int dfs(int pos,int dis)
} }return 0;
}inline int dinic()
return ans;
}int main()
} for(int i=1,w;i<=m;i++)
w=read(),add(i+n,t,w),add(t,i+n,0);
printf("%d",sum-dinic());
}
轉化:先拆點為\(v,v\),原圖中\(u\)和\(v\)有邊,連\(u,v\)即可。最小路徑\(=\)點數\(-\)最大匹配。
變式:\([sdoi2010]\)星際競速:考慮跳躍,無論從哪個點跳到\(i\),花費均為\(a[i]\),所以可以建\(s\)到\(v\),容量為\(a[i]\)的邊。(下附**)
#includeusing namespace std;
inline int read()
while(x!=eof&&x>='0'&&x<='9')
return w*f;
}const int n=300010;
int n,m,sum,s,t,flo[n],v[n],ans;
int head[n],num_edge,d[n],cur[n];
struct edge[n*10];
inline void add(int from,int to,int dis,int cos)
inline bool bfs()
} return d[t]<0x3f3f3f3f?1:0;
}inline int dfs(int pos,int dis)
} }return 0;
}inline int dinic()
return ans;
}int main()*2+……+t_1*p\)。
可以看出乙個修車工所修的第倒數\(k\)個車對答案的貢獻為\(k*t\)。所以我們可以將每個修車工拆為\(n\)個時間段,表示倒數幾個修,將每個車和拆開的點建邊,費用為時間段編號乘花費時間即可。(下附**)
#includeusing namespace std;
inline int read()
while(x!=eof&&x>='0'&&x<='9')
return w*f;
}const int n=6000,m=100010;
int n,m,num_edge,s,t,ans;
int d[n],head[n],v[n],flo[n],cur[n];
struct edge edge[m];
inline void add(int from,int to,int dis,int cos)
inline bool bfs()
} return d[t]<0x3f3f3f3f?1:0;
}inline int dfs(int pos,int dis)
} }return 0;
}inline int dinic()
return ans;
}int main()
for(int i=1;i<=n;i++) add(s,i,1,0),add(i,s,0,0);
for(int i=1;i<=n*m;i++) add(i+n,t,1,0),add(t,i+n,0,0);
printf("%.2lf",(double)dinic()/(double)n);
}
\(to\)
\(be\)
\(continued...\)
(怎麼辦我好想咕)
網路流小結
咱也不敢寫總結只能說小結因為到現在會的還是太少 也不說自己弱了因為即使是真的說了又有什麼用呢 還是老老實實自閉吧 士兵占領 最大流的板子,但是一開始想偏了。正解是用最大流求出並集,然後用全集減掉。緊急疏散 需要考慮的問題是每個門在一秒只能出乙個人,用到乙個拆點的思想。按照時間拆點,然後在各個空地建出...
網路流小結
bzoj 1001 狼抓兔子 最小割 優化做的足的dinic能過 平面圖轉對偶圖跑最短路 還沒寫。bzoj 1877 晨跑 拆點 限制每個點跑一次吧每個點拆成兩個中間加一條權值為1的邊 bzoj 1066 蜥蜴 裸最大流 bzoj 1927 星際競速 建立附加源點流量為能夠瞬間移動的次數,每個點拆點...
題目小結 網路流
東拼拼,西湊湊,不就又水出一篇部落格嗎?例 1.text 首先可以想到在 1,n 列舉匯點,檢驗最大流是否為企鵝總數。每個點初始的企鵝數可以由 s rightarrow i 的邊表示,那跳出的企鵝呢?因為跳到哪個冰塊是未知的,所以不妨將 i 拆成兩個點 在入點與出點之間連邊權為跳出企鵝數的邊。例 2...