原始對偶費用流

2022-07-05 22:57:14 字數 1645 閱讀 7474

用 \(dijkstra\) 代替 \(spfa\)。link,但是這篇部落格的**上來就跑 \(dijkstra\),複雜度可能會被卡成指數。

\(\text:\)

interval graph

\(\text:\)

滿足題意的充要條件:每個點至多被兩個區間覆蓋。

\(i\rightarrow i+1\) 連一條流量為 \(2\),費用為 \(0\) 的邊。

\(l\rightarrow r+1\) 連一條流量為 \(1\),費用為 \(-w\) 的邊。

然後跑最小費用最大流。此題需要用 \(primal-dual\) 優化。

但是第一次跑 \(dijkstra\) 的時候有負權,所以先把邊權都變成正的,再跑 \(dijkstra\)。

\(\text:\)

#include #pragma gcc optimize(3)

#define int long long

#define ri register

#define mk make_pair

#define fi first

#define se second

#define pb push_back

#define eb emplace_back

#define is insert

#define es erase

using namespace std; const int n=500010, inf=1e18;

inline int read()

while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+(ch^48), ch=getchar();

return s*w;

}int n,ans;

struct link g[n];

int s,t,dis[n],pre[n],h[n],book[n];

int head[n],maxe,cur[n]; struct edge e[n<<2];

inline void add(int u,int v,int w1,int w2)

struct node };

inline bool dijk()

); while(!q.empty())

); }

} }return ~pre[t];

}signed main(); }

for(ri int i=0;i0&&dis[v]>dis[x]+e[i].cost)

dis[v]=dis[x]+e[i].cost, pre[v]=i;

} if(pre[t]==-1) return puts("0")&0;

for(ri int i=0;i<=t;i++) if(dis[i]int res=inf;

for(ri int i=t;i!=s;i=e[pre[i]^1].to) res=min(res,e[pre[i]].rdis);

for(ri int i=t;i!=s;i=e[pre[i]^1].to)

ans+=res*h[t];

while(dijk())

ans+=res*h[t];

} printf("%lld\n",-ans);

return 0;

}

原始對偶費用流ver2 0 hdu4744

這場比賽我就不多說什麼了。幾乎整場都在寫計算幾何,恰好三維計算幾何又是我的軟肋,後面的題基本都沒看。建圖就不多說了,挺水的,標算不是費用流,但我聽說有人zkw費用流過了,於是我就寫個原始對偶費用流,但是居然超了,本機測試60組極限1050 ms 於是進行優化,lyp跟我說過一次反向spfa就可以di...

學習筆記 最小費用流之原始對偶

兼具zkw和spfa的優點,折中的一種演算法,通過spfa跑出最短路,然後更改邊的權值 加上dis from dis to 那麼如果為0就是在from到to最短路上的點,相當於一種分層 個人理解 就可以用多路增廣來搞了。而這裡的spfa除了第一次外甚至可以拿dij來替換,不過因為加了slf優化的sp...

Primal Dual 原始對偶

不是費用流都需要用 spfa 嗎。眾所周知,spfa 去世了,然後網路流顯然有負邊。於是我們可以像 johnson 全源最短路一樣,給邊加上勢能,具體實現看我之前的 部落格 啦。然後對於每一次跑 dijkstra 然後得到最短路,把勢能要再加上這個最短路,可以證明這樣操作一次圖上不會再有負邊。也正因...