昨天写最大获利 的时候惊奇的发现我的dinic模板竟然挂了。。。
现在刚刚调对。。。。
这个模板。。。一个很大的优点就是他很好理解,基本上是抄的lrj的白书,但是同时一个很明显的缺点就是vector太慢了!!!!
有时间我会改进成前向星版本的。。。
如果这个模板啥时候TLE了大家不要激动。。。只需要把vecotor改成前向星就可以了
比如说我的poj3680.。。。。。。
模板基本没有什么难理解的地方
注意每次增广都都只在残留网络中进行
还有一些小的优化
比如cur数组的应用
这些都挺好理解的
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define MAX 600100
#define inf 0x7fffffff
using namespace std;
int n,m;
struct dinic
{
struct Edge
{
int from,to,cap,filp;
};
vector<int>g[MAX];
vector<Edge>edge;
void add_edge(int From,int To,int Cap,int Cap_)
{
edge.push_back((Edge){From,To,Cap,0});
edge.push_back((Edge){To,From,Cap_,0});
int mm=edge.size();
g[From].push_back(mm-2);
g[To].push_back(mm-1);
}
int s,t;
int cur[MAX];
int dis[MAX];
int done[MAX];
bool bfs()
{
memset(done,0,sizeof(done));
queue<int> q;
q.push(s);
done[s]=1;
dis[s]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int w=0;w<g[now].size();w++)
{
Edge &e=edge[g[now][w]];
if(done[e.to]==0&&e.cap>e.filp)
{
done[e.to]=1;
dis[e.to]=dis[now]+1;
q.push(e.to);
}
}
}
return done[t];
}
int dfs(int x,int a)
{
if(x==t||a==0)
return a;
int flow=0,f;
for(int &w=cur[x];w<g[x].size();w++)
{
Edge &e=edge[g[x][w]];
if(dis[e.to]==dis[x]+1&&(f=dfs(e.to,min(a,e.cap-e.filp)))>0)
{
e.filp+=f;
edge[g[x][w]^1].filp-=f;
flow+=f;
a-=f;
if(!a)
break;
}
}
return flow;
}
int maxfile(int S,int T)
{
this->s=S;
this->t=T;
int answer=0;
while(bfs())
{
memset(cur,0,sizeof(cur));
answer+=dfs(s,inf);
}
return answer;
}
}solve;
int main()
{
scanf("%d%d",&n,&m);
int s,t;
s=0;
t=n*2+1;
for(int i=1;i<=n;i++)
{
int a1,a2;
scanf("%d%d",&a1,&a2);
solve.add_edge(s,i,a1,0);
solve.add_edge(i,t,a2,0);
}
for(int i=1;i<=m;i++)
{
int a1,a2,a3;
scanf("%d%d%d",&a1,&a2,&a3);
solve.add_edge(a1,a2,a3,a3);
}
int answer=solve.maxfile(s,t);
printf("%d\n",answer);
return 0;
}
好吧由于写一个水题的时候vector又被卡了所以很不爽
然后就终于决定来改下原来的模板了。。。
对于这个题
vector跑了4891ms
前向星跑了4829ms
但是如果数据再大些的话前向星的优势会更大。。
所以都贴上来吧
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define MAX 600100
#define inf 0x7fffffff
using namespace std;
int n,m;
struct dinic
{
struct Edge
{
int from,to,cap,filp;
};
vector<int>g[MAX];
vector<Edge>edge;
void add_edge(int From,int To,int Cap,int Cap_)
{
edge.push_back((Edge){From,To,Cap,0});
edge.push_back((Edge){To,From,Cap_,0});
int mm=edge.size();
g[From].push_back(mm-2);
g[To].push_back(mm-1);
}
int s,t;
int cur[MAX];
int dis[MAX];
int done[MAX];
bool bfs()
{
memset(done,0,sizeof(done));
queue<int> q;
q.push(s);
done[s]=1;
dis[s]=0;
while(!q.empty())
{
int now=q.front();
q.pop();
for(int w=0;w<g[now].size();w++)
{
Edge &e=edge[g[now][w]];
if(done[e.to]==0&&e.cap>e.filp)
{
done[e.to]=1;
dis[e.to]=dis[now]+1;
q.push(e.to);
}
}
}
return done[t];
}
int dfs(int x,int a)
{
if(x==t||a==0)
return a;
int flow=0,f;
for(int &w=cur[x];w<g[x].size();w++)
{
Edge &e=edge[g[x][w]];
if(dis[e.to]==dis[x]+1&&(f=dfs(e.to,min(a,e.cap-e.filp)))>0)
{
e.filp+=f;
edge[g[x][w]^1].filp-=f;
flow+=f;
a-=f;
if(!a)
break;
}
}
return flow;
}
int maxfile(int S,int T)
{
this->s=S;
this->t=T;
int answer=0;
while(bfs())
{
memset(cur,0,sizeof(cur));
answer+=dfs(s,inf);
}
return answer;
}
}solve;
int main()
{
scanf("%d%d",&n,&m);
int s,t;
s=0;
t=n*2+1;
for(int i=1;i<=n;i++)
{
int a1,a2;
scanf("%d%d",&a1,&a2);
solve.add_edge(s,i,a1,0);
solve.add_edge(i,t,a2,0);
}
for(int i=1;i<=m;i++)
{
int a1,a2,a3;
scanf("%d%d%d",&a1,&a2,&a3);
solve.add_edge(a1,a2,a3,a3);
}
int answer=solve.maxfile(s,t);
printf("%d\n",answer);
return 0;
}