您的位置:首页 > 理论基础 > 计算机网络

初涉网络流 POJ 1459 Power Network

2014-07-03 00:04 316 查看
怒搞一下午网络流,又去我一块心病。

从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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: