這個題就是求最小割邊數目,太菜了,這個題交的時候沒法看是wa還是tle,結果連交三發,全都是紅,我有些懷疑tle,但是又不敢肯定,(mdzz,200點,1000邊稠密圖還用dinic),當時也蒙了,我就盯著每秒重新整理看了11頁,看的眼睛都花了,終於找到tle。果斷上sap,終於是過了。mdzz,這周智障的格外厲害。
關於最小割邊的邊數量,我們用e代表最大邊數量。
每條邊的流量記為w,我們存圖時,存入的為(w*(e+1)+1)
為什麼呢?
我們可以把最後乙個1看成每條邊的標記,這標記最後取,這樣只有著天邊全取時才會把這個1加入到最大流中,代表這條增廣路中限制流量的那條邊取到了,而這條邊恰恰是最小割的組成部分。
這樣最大流為ans/(e+1),最小割邊數量為ans%(e+1)
code:
#include
#include
#include
#include
#include
#include
#include
#include
//a&3==a%4
using
namespace
std;
#define ll long long
#define intt long long
#define mem(a) memset(a,0,sizeof(a))
const
double eps=1e-8;
const
int maxn = 1010;//點數的最大值+10
const
int maxm = 10010;//邊數的最大值+10
const
int inf = 0x3f3f3f3f;
struct edge
edge[maxm];
int tol;
int head[maxn];
int gap[maxn],dep[maxn],cur[maxn];
void init()
void addedge(int u,int v,int w,int rw = 0)
int q[maxn];
void bfs(int start,int end)
}}int s[maxn];
ll sap(int start,int end,int n)
for(int i = 0;i < top;i++)
ans += (ll)(min);
top = inser;
u = edge[s[top]^1].to;
continue;
}bool flag = false;
int v;
for(int i = cur[u]; i != -1; i = edge[i].next)
}if(flag)
int min = n;
for(int i = head[u]; i != -1; i = edge[i].next)
if(edge[i].cap - edge[i].flow && dep[edge[i].to] < min)
gap[dep[u]]--;
if(!gap[dep[u]])return ans;
dep[u] = min + 1;
gap[dep[u]]++;
if(u != start)u = edge[s[--top]^1].to;
}return ans;
}int main()
ll res=sap(s,t,n);
res=res%(ll)(maxm);
cout
0;}
poj 3469 最大流 最小割 SAP演算法模板
題目 題意 有雙核處理器,有n個任務,給出每個任務在分別在兩個處理核心上工作的花費,然後有m行,每行給出兩個任務,如果兩個任務不在同乙個處理核心上工作,那麼將有額外的花費。求最小花費 思路 最小割。之前用dinic演算法做的,加上當前弧優化6000ms。省賽的時候yjj看到我的最大流板子是 dini...
全域性最小割stoer wagner c 模板
include using namespace std define maxn 110 int graph maxn maxn int v maxn i為結點初始編號,v i 為結點當前編號,便於刪除結點並使序號始終連續 int wage maxn 該點加入之前集合中的所有頂點到該點的邊權之和 bo...
流量最小HDU 3491 最小割
在寫這篇文章之前,已經寫過了幾篇關於改流量最小主題的文章,想要了解的朋友可以去翻一下之前的文章 題意 有n個都會,每乙個都會有定一數量的察警,有一群小偷,從都會s,到t,問起碼須要多少察警可以使小偷到不了t都會。將每乙個都會的察警數量當作流量,那麼題問就轉化成求s t的最小割。將每乙個點拆成i i ...