poj3469 DINIC模板(vector+前向星)

来源:互联网 发布:网购商城农村淘宝 编辑:程序博客网 时间:2024/06/04 18:19

昨天写最大获利 的时候惊奇的发现我的dinic模板竟然挂了。。。

现在刚刚调对。。。。


这个模板。。。一个很大的优点就是他很好理解,基本上是抄的lrj的白书,但是同时一个很明显的缺点就是vector太慢了!!!!

有时间我会改进成前向星版本的。。。

如果这个模板啥时候TLE了大家不要激动。。。只需要把vecotor改成前向星就可以了

比如说我的poj3680.。。。。。。


模板基本没有什么难理解的地方

注意每次增广都都只在残留网络中进行

还有一些小的优化

比如cur数组的应用


这些都挺好理解的

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<vector>#include<queue>#define MAX 600100#define inf 0x7fffffffusing 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 0x7fffffffusing 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;}

0 0