标签:sig 复杂 Fix ase lib 网络流 can += template
怒搞一下午网络流,又去我一块心病。
从2F到SAP再到Dinic最终过掉了。
但是书上说Dinic的时间复杂度为v*v*e。感觉也应该超时的啊,但是过掉了,好诡异。
后两种算法都是在第一种的基础上进行优化。
第一种方法就是不停的寻找增广路。后两种引进了层次网络的概念。第三种又改善了寻找增广路的方法。
如今仅仅能理解到这里了。。
。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define _INF 0x3f3f3f3f
#define Mod 6000007
using namespace std;
struct E
{
int u,v,Max,now,next;
}edge[30000];
int Top;
int head[300];
void Link(int u,int v,int w)
{
edge[Top].u = u;
edge[Top].v = v;
edge[Top].Max = w;
edge[Top].now = 0;
edge[Top].next = head[u];
head[u] = Top++;
}
struct P
{
int pre,now,floor;
bool mark;
}sta[300];
void Modify(int a,int t)
{
while(t != 1)
{
edge[sta[t].pre].now += a;
t = edge[sta[t].pre].u;
}
}
int SAP(int s,int t,int n)
{
for(int i = 1;i <= n; ++i)
sta[i].mark = false;
queue<int> q;
q.push(s);
sta[s].mark = true;
sta[s].now = 2000000000;
sta[s].pre = -1;
while(q.empty() == false)
{
if(sta[t].mark && sta[t].now)
{
Modify(sta[t].now,t);
return sta[t].now;
}
int f = q.front();
q.pop();
for(int p = head[f];p != -1; p = edge[p].next)
{
if(sta[edge[p].v].mark == false && sta[edge[p].u].floor == sta[edge[p].v].floor-1 && sta[edge[p].u].floor < sta[t].floor)
{
sta[edge[p].v].now = min(sta[f].now,edge[p].Max - edge[p].now);
if(sta[edge[p].v].now == 0)
continue;
sta[edge[p].v].pre = p;//记录边的存储位置
sta[edge[p].v].mark = true;
q.push(edge[p].v);
}
}
}
return 0;
}
void Updata_Floor(int s,int t,int n)
{
queue<int> q;
for(int i = 0;i <= n; ++i)
sta[i].mark = false,sta[i].floor = n;
q.push(s);
sta[s].mark = true;
sta[s].floor = 1;
while(q.empty() == false)
{
int f = q.front();
q.pop();
if(sta[t].mark && sta[t].floor <= sta[f].floor)
return ;
for(int p = head[f];p != -1; p = edge[p].next)
{
if(sta[edge[p].v].mark == false && edge[p].now < edge[p].Max)
{
sta[edge[p].v].mark = true;
sta[edge[p].v].floor = sta[f].floor + 1;
q.push(edge[p].v);
}
}
}
}
int dfs(int s,int t,int a)
{
if(s == t)
return a;
int f = 0;
for(int p = head[s],temp = 0;p != -1; p = edge[p].next)
{
if((sta[edge[p].v].floor < sta[t].floor || edge[p].v == t) && sta[edge[p].v].floor == sta[s].floor+1 && edge[p].now < edge[p].Max)
{
temp = dfs(edge[p].v,t,min(a-f,edge[p].Max-edge[p].now));
edge[p].now += temp;
f += temp;
}
}
return f;
}
int Dinic(int s,int t,int n)
{
return dfs(s,t,200000000);
}
int Cal_Max_Flow(int s,int t,int n)
{
int temp,f = 0;
do
{
Updata_Floor(s,t,n);
//temp = SAP(s,t,n);
temp = Dinic(s,t,n);
f += temp;
}while(temp);
return f;
}
int main()
{
char s[50];
int i,n,np,nc,m,u,v,w;
while(scanf("%d %d %d %d",&n,&np,&nc,&m) != EOF)
{
memset(head,-1,sizeof(head));
Top = 0;
for(i = 0;i < m; ++i)
{
scanf("%s",s);
sscanf(s,"(%d,%d)%d",&u,&v,&w);
Link(u+2,v+2,w);
}
for(i = 0;i < np; ++i)
{
scanf("%s",s);
sscanf(s,"(%d)%d",&u,&w);
Link(1,u+2,w);
}
for(i = 0;i < nc; ++i)
{
scanf("%s",s);
sscanf(s,"(%d)%d",&u,&w);
Link(u+2,n+2,w);
}
printf("%d\n",Cal_Max_Flow(1,n+2,n+2));
}
return 0;
}
标签:sig 复杂 Fix ase lib 网络流 can += template
原文地址:https://www.cnblogs.com/mqxnongmin/p/10966684.html