ACM模板库

ACM模板库


有源汇最小费用流(可行流与最大流)

<pre><code class="language-cpp">//可行流保证钱最少,最大流保证流最大 #include &lt;iostream&gt; #include &lt;cstring&gt; #include &lt;queue&gt; using namespace std; typedef int ll; typedef pair&lt;ll, int&gt; P; const int maxn = 5005; const int maxm = maxn * maxn * 2; const ll INF = 0x3f3f3f3f; struct Edge{ int to; int next; ll cap; ll cost; }; Edge edge[maxm]; int head[maxn]; int tol; int n, m; void init(){ tol = 0; memset(head, -1, sizeof(head)); } void addedge(int u, int v, ll ca, ll co, ll rca = 0){ edge[tol].to = v; edge[tol].cap = ca; edge[tol].cost = co; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = rca; edge[tol].cost = -co; edge[tol].next = head[v]; head[v] = tol++; } namespace Vflows{ int h[maxn], prevv[maxn], preve[maxn]; ll dist[maxn]; pair&lt;ll, ll&gt; min_cost_flow(int s, int t, int n){//源点,汇点,点的个数 ll res = 0, ans = 0;//res费用,ansflow for(int i = 1; i &lt;= n; i++) h[i] = 0; while(233){ priority_queue&lt;P, vector&lt;P&gt;, greater&lt;P&gt; &gt;que; for(int i = 1; i &lt;= n; i++) dist[i] = INF; dist[s] = 0; que.push(P(0, s)); while(que.size()){ P p = que.top(); que.pop(); int v = p.second; if(dist[v] &lt; p.first) continue; for(int i = head[v]; ~i; i = edge[i].next){ Edge &amp;e = edge[i]; if(e.cap &gt; 0 &amp;&amp; dist[e.to] &gt; dist[v] + e.cost + h[v] - h[e.to]){ dist[e.to] = dist[v] + e.cost + h[v] - h[e.to]; prevv[e.to] = v; preve[e.to] = i; que.push(P(dist[e.to], e.to)); } } } if(dist[t] == INF) break; for(int i = 1; i &lt;= n; i++) h[i] += dist[i]; ll d = INF; for(int i = t; i != s; i = prevv[i]){ d = min(d, edge[preve[i]].cap); } res += d * h[t]; ans += d; for(int i = t; i != s; i = prevv[i]){ edge[preve[i]].cap -= d; edge[preve[i]^1].cap += d; } } return make_pair(res, ans); } } int num[maxn]; int main(){ scanf("%d", &amp;n); for(int i = 1; i &lt;= n; i++){ scanf("%d", &amp;num[i]); } init(); int s = n+1, t = n+2; for(int i = 1; i &lt;= n; i++){ if(num[i] == 1) addedge(s, i, 1, 0); else addedge(i, t, 1, 0); if(num[i] == 0) continue; for(int j = 1; j &lt;= n; j++){ if(i == j || num[j] == 1) continue; addedge(i, j, 1, max(i, j) - min(i, j)); } } pair&lt;ll, ll&gt; p = Vflows::min_cost_flow(s, t, n+2); cout &lt;&lt; p.first; } </code></pre>

页面列表

ITEM_HTML