LibreOJ #101. 最大流
阿新 • • 發佈:2017-06-25
nic lan sta gis false [] 最大流 count 技術
二次聯通門 : LibreOJ #101. 最大流
本想著去這個OJ刷刷板子題
結果被這道最大流給坑了。。。
10^6的網絡流。。。。
一開始隨手寫了個dinic
交上去50
有點懵。。後又加了些奇怪的優化
還是50
把class封裝去掉
恩, 變成70了
然後就沒有然後了
TLE了一整頁
後來知道要加當前弧優化才能過
就先去學。
學完後, 加上後
還是70分過不了。。非常絕望啊。。
/* LibreOJ #101. 最大流(50) Dinic + 當前弧優化 用class封裝了起來 50分 */ #include <cstring> #include<cstdio> #include <queue> #define Max 1000090 #define INF 1e9 void read (int &now) { now = 0; register char word = getchar (); while (word < ‘0‘ || word > ‘9‘) word = getchar (); while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } } int N, M, S, T; inline int min (int a, int b) { return a < b ? a : b; } class Net_Flow_Type { private : int __to[Max * 10]; int __next[Max * 10]; int __flow[Max * 10]; int Edge_Count;int edge_list[Max]; int deep[Max], Answer; int Queue[Max * 10]; int Head, Tail; int __tech_[Max]; public : Net_Flow_Type () { Edge_Count = 1; Answer = 0; } int Flowing (int now, int flow) { if (flow <= 0 || now == T) return flow; int pos = 0, res; for (int i = __tech_[now]; i; i = __next[i]) { if (deep[__to[i]] != deep[now] + 1 || __flow[i] <= 0) continue; res = Flowing (__to[i], min (flow, __flow[i])); if (res > 0) { flow -= res; pos += res; __flow[i] -= res; __flow[i ^ 1] += res; if (__flow[i]) __tech_[now] = i; if (flow <= 0) return pos; } } return pos; } inline void Add_Edge (int from, int to, int flow) { Edge_Count ++; __to[Edge_Count] = to; __next[Edge_Count] = edge_list[from]; edge_list[from] = Edge_Count; Edge_Count ++; __to[Edge_Count] = from; __next[Edge_Count] = edge_list[to]; edge_list[to] = Edge_Count; __flow[Edge_Count - 1] = flow; __flow[Edge_Count] = 0; } void Insert_edges () { for (int i = 1, from, to, flow; i <= M; i ++) { read (from); read (to); read (flow); this->Add_Edge (from, to, flow); } } bool Bfs (int Start) { memset (deep, -1, sizeof deep); Head = 0, Tail = 1; Queue[Head] = Start; deep[Start] = 0; register int now; while (Head < Tail) { now = Queue[Head]; Head ++; for (int i = edge_list[now]; i; i = __next[i]) if (deep[__to[i]] == -1 && __flow[i]) { deep[__to[i]] = deep[now] + 1; if (__to[i] == T) return true; Queue[Tail ++] = __to[i]; } } return deep[T] != -1; } int Dinic () { while (Bfs (S)) { for (int i = 0; i <= N; i ++) __tech_[i] = edge_list[i]; Answer += Flowing (S, INF); } return Answer; } }; Net_Flow_Type Make; int main (int argc, char *argv[]) { read (N); read (M); read (S); read (T); Make.Insert_edges (); printf ("%d", Make.Dinic ()); return 0; }
/* LibreOJ #101. 最大流(70) Dinic + 當前弧優化 沒有封裝 70分 */ #include <iostream> #include <cstring> #include <cstdio> #define Max 1000010 #define INF 1e8 using namespace std; void read (int &now) { now = 0; char word = getchar (); while (word < ‘0‘ || word > ‘9‘) word = getchar (); while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } } inline int min (int a, int b) { return a < b ? a : b; } int __tech_[Max]; struct Edge { int to; int next; int flow; }edge[Max * 20]; int Edge_Count = 1, edge_list[Max]; int deep[Max]; inline void AddEdge (int from, int to, int flow) { Edge_Count++; Edge *now = &edge[Edge_Count]; now->flow = flow; now->to = to; now->next = edge_list[from]; edge_list[from] = Edge_Count; } int N, M, S, T; int Get_Flow (int now, int flow) { if (flow <= 0 || now == T) return flow; int res = 0, pos; for (int i = __tech_[now]; i; i = edge[i].next) { if (deep[edge[i].to] != deep[now] + 1 || edge[i].flow <= 0) continue; pos = Get_Flow (edge[i].to, min (flow, edge[i].flow)); res += pos; flow -= pos; edge[i].flow -= pos; edge[i ^ 1].flow += pos; if (edge[i].flow) __tech_[now] = i; if (flow <= 0) return res; } return res; } int queue[Max * 10]; int Answer; void Bfs () { int Head, Tail; int now; bool flag; while (true) { memset (deep, -1, sizeof deep); Head = 0, Tail = 1; queue[0] = S; deep[S] = 0; flag = false; while (Head < Tail) { now = queue[Head++]; for (int i = edge_list[now]; i; i = edge[i].next) if (deep[edge[i].to] < 0 && edge[i].flow) { deep[edge[i].to] = deep[now] + 1; if (edge[i].to == T) { flag = true; break; } queue[Tail++] = edge[i].to; } if (flag == true) break; } if (deep[T] < 0) break; for (int i = 0; i <= N; i ++) __tech_[i] = edge_list[i]; Answer += Get_Flow (S, INF); } } int main (int argc, char *argv[]) { read (N); read (M); read (S); read (T); int x, y, z; for (int i = 1; i <= M; i++) { read (x); read (y); read (z); AddEdge (x, y, z); AddEdge (y, x, 0); } Bfs (); printf ("%d", Answer); return 0; }
/* 此為std 跑的飛快。。。 不是很懂為什麽 明明一樣的。。。 */ #include <cstdio> #include <iostream> #include <cstring> #include <vector> using namespace std; const int maxn=1000005; const int INF=0x3f3f3f3f; inline int read (int &now) { now = 0; char word = getchar (); while (word < ‘0‘ || word > ‘9‘) word = getchar (); while (word >= ‘0‘ && word <= ‘9‘) { now = now * 10 + word - ‘0‘; word = getchar (); } } struct edge { int to,rev,cap; edge() {} edge(int t,int r,int c) { to=t; rev=r; cap=c; } }; vector<edge> vec[maxn]; int n,m,s,t,que[maxn],h,tail,level[maxn]; void add_edge(int from,int to,int cap) { vec[from].push_back(edge(to,vec[to].size(),cap)); vec[to].push_back(edge(from,vec[from].size()-1,0)); } bool bfs() { memset(level,-1,sizeof(level)); level[que[h=tail=1]=s]=0; int x,y; while (h<=tail) { x=que[h++]; for (int i=0; i<vec[x].size(); i++) { y=vec[x][i].to; if (vec[x][i].cap==0||level[y]!=-1) continue; level[y]=level[x]+1,que[++tail]=y; } } return level[t]!=-1; } int dfs(int x,int f) { if (x==t) return f; int used=0,w,y; for (int i=0; i<vec[x].size(); i++) { y=vec[x][i].to; if (vec[x][i].cap==0||level[y]!=level[x]+1) continue; w=dfs(y,min(f-used,vec[x][i].cap)); used+=w,vec[x][i].cap-=w,vec[y][vec[x][i].rev].cap+=w; if (used==f) return f; } if (used!=f) level[x]=-1; return used; } int max_flow() { int flow=0; while (bfs()) flow+=dfs(s,INF); return flow; } int main() { read (n); read (m); read (s); read (t); int u, v, c; for (int i=0; i<m; i++) { read (u); read (v); read (c); add_edge(u,v,c); } printf ("%d\n",max_flow()); return 0; }
LibreOJ #101. 最大流