用 \(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 然後得到最短路,把勢能要再加上這個最短路,可以證明這樣操作一次圖上不會再有負邊。也正因...