序:
在以前的文章中實現了不利用STL實現EK算法,效率也較高。此次咱們企圖簡化代碼,減小變量的使用與手寫模擬的代碼。c++
注意:vector等STL的container在不開O2優化的時候實現同一個效果廣泛比手寫要慢。算法
源代碼以下:markdown
/* About: Max_flow_EK_vector Auther: kongse_qi Date:2017/04/22 */
#include <bits/stdc++.h>
#define INF 0x3f3f3f
#define maxn 20005
#define maxm 200005
#define g_t Get_Int()
#define p_b(x) push_back(x)
#define read(x) g_t, x = in
using namespace std;
/* 部分宏是爲了簡潔好看 */
struct Edge
{
int from;
int to;
int weight;
Edge(){}
Edge(int f, int t, int w):
from(f), to(t), weight(w){}
};//邊表
vector<Edge> edge;//存全部弧的信息
vector<int> arc[maxn];//每一個節點相連的弧的編號
typedef vector<int>::iterator iterator_t;//迭代器
int n, m, st, en, max_flow;
iterator_t pre[maxn];//記錄上一條弧的編號便於回溯
char *X, *T, *Buffer, c;//讀入優化
int in;
bool flag = true;
void Get_All()
{
fseek(stdin, 0, SEEK_END);
int file_lenth = ftell(stdin);
Buffer = (char*)malloc(file_lenth);
rewind(stdin);
T = (X = Buffer)+fread(Buffer,1, file_lenth, stdin);
c = *X;
}
void Get_Int()
{
in = 0;
while(c < '0' || c > '9') c = *++X;
while(c >= '0' && c <= '9')
{
in = in*10+c-'0';
c = *++X;
}
return ;
}
void Init()//當多組數據的時候
{
edge.resize(0);
for(unsigned i = 0; i != n*2; ++i)
{
arc[i].resize(0);
}
max_flow = 0;
return ;
}
void Add_Edge(int st, int en, int weight)
{
edge.p_b(Edge(st, en, weight));
edge.p_b(Edge(en, st, 0));//該弧信息與反向弧
arc[st].p_b(edge.size()-2);//編號
arc[en].p_b(edge.size()-1);
return ;
}
void Read()
{
int a, b, c;
read(n), read(m);//見宏定義
read(st), read(en);
for(unsigned i = 0; i != m; ++i)
{
read(a), read(b), read(c);
Add_Edge(a, b, c);
}
return ;
}
bool Bfs(int st, int en)
{
queue<int> q;
int cur, ne, we;
bool vis[maxn];
memset(vis, 0, sizeof vis);
q.push(st);
vis[st] = true;
while(!q.empty())
{
cur = q.front(), q.pop();
for(iterator_t i = arc[cur].begin(); i != arc[cur].end(); ++i)//迭代器遍歷vector
{
ne = edge[*i].to;
we = edge[*i].weight;
if(vis[ne] == false && we > 0)
{
q.push(ne);
pre[ne] = i;//記錄當前的弧編號
vis[ne] = true;
pre[ne] = i;
if(ne == en) return true;
}
}
}
return false;
}
void EK(int st, int en)
{
int minn;
while(Bfs(st, en))
{
minn = INF;
for(unsigned i = en; i != st; i = edge[*pre[i]].from)
{
minn = min(minn, edge[*pre[i]].weight);
}
for(unsigned i = en; i != st; i = edge[*pre[i]].from)
{
edge[*pre[i]].weight -= minn;
edge[*pre[i]^1].weight += minn;//因爲弧和它的反向弧在讀入的時候是兩兩一塊兒的,故能夠用異或獲得它反向弧的編號
}
max_flow += minn;
}
return ;
}
int main()
{
freopen("test.in", "r", stdin);
Get_All();
Init();
Read();
EK(st, en);
printf("%d\n", max_flow);
return 0;
}
基本意思與非vector實現時是同樣的。
效率:很是慢!比非vector實現的要慢1倍,要不是讀入優化比較狠確定要超時。大數據
建議OI比賽的時候不使用STL容器,除非使用例如map等極難手寫實現的容器。
否則就等着後面的大數據TLE吧。優化
箜瑟_qi 2017.04.22 22:14ui