HDU 3549 Flow Problem【网络流入门题】
来源:互联网 发布:win7美化mac 编辑:程序博客网 时间:2024/05/30 23:37
没找到比较好的博客介绍网络流,可以看下白书(电子书的224页)
Edmonds-Karp(EK)算法 O(V*E*E) 124ms
#include <cstdio>#include <cmath>#include <cstring>#include <set>#include <stack>#include <queue>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define ll long long#define INF 0x7FFFFFFF#define INT_MIN -(1<<31)#define eps 10^(-6)#define Q_CIN ios::sync_with_stdio(false)#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define REV( i , n ) for ( int i = n - 1 ; i >= 0 ; -- i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- i )#define CLR( a , x ) memset ( a , x , sizeof (a) )#define RE freopen("in.txt","r",stdin)#define WE freopen("out.txt","w",stdout)#define NMAX 1002#define min(a,b) ((a)>(b)?(b):(a))#define Dian_NAX 21int flow[Dian_NAX][Dian_NAX]; //边实际流量int cap[Dian_NAX][Dian_NAX]; //边容量int pre[NMAX]; //增广路径int res[NMAX]; //残余网络int n; //点int EK(int s,int t){ queue<int>q; int ans = 0; CLR(flow,0); while(true) { CLR(res,0); res[s] = INF; //源点无限大 q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); for(int v=1;v<=n;v++) if(!res[v] && flow[u][v] < cap[u][v]) { pre[v] = u; q.push(v); res[v] = min(res[u],cap[u][v] - flow[u][v]); } } if(res[t] == 0) //找不到增广路就退出 break; for(int u = t;u != s; u=pre[u]) { flow[pre[u]][u] += res[t]; flow[u][pre[u]] -= res[t]; //反向边 } ans += res[t]; } return ans;}int main(){ int a,b,c,t,m; int test = 1; // RE; scanf("%d",&t); while(t--) { CLR(cap,0); scanf("%d%d",&n,&m); while(m--) { scanf("%d%d%d",&a,&b,&c); cap[a][b] +=c; } printf("Case %d: %d\n",test++,EK(1,n)); } return 0;}
Dinic 124ms
#include <string.h>#include <iostream>#include <cstdio>using namespace std;#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("output.txt","w",stdout);#define debug(x) cout<<#x<<":"<<(x)<<endl;const int maxn=16;int tab[maxn][maxn],dis[maxn],n,m; //tab为流量,dis为层次//bfs找层次图int bfs(int s,int t){ int q[maxn],head=0,tail=0; q[tail++]=s; memset(dis,-1,sizeof(dis)); dis[s]=0; while(head<tail) { int cur=q[head++]; for(int i=1;i<=n;i++) { if(dis[i]<0&&tab[cur][i]>0) { dis[i]=dis[cur]+1; q[tail++]=i; } } } if(dis[t]>0) return 1; return 0; //dis[t]=-1:路不通}//dfs为一次增广,s->tint dfs(int s,int t,int low)//Low为增广路径上的最小流量{ int flow=0; if(s==t) return low; //到汇点直接返回目前为止的最小流量 for(int i=1;i<=n;i++) { //在下一层里找 if(tab[s][i]>0 &&dis[i]==dis[s]+1 &&(flow=dfs(i,t,min(low,tab[s][i])))) { tab[s][i]-=flow; //不断的减流量 tab[i][s]+=flow; return flow; //能到汇点 } } return 0;}int main() {// RE int a,b,c,t; scanf("%d",&t); for(int te=1;te<=t;te++) { scanf("%d%d",&n,&m); CLR(tab,0); //流量初始化为0 while(m--) { scanf("%d%d%d",&a,&b,&c); tab[a][b]+=c; } int ans=0,tans=0; while(bfs(1,n)) //直到源点不能到汇点为止 while(tans=dfs(1,n,0x7FFFFFFF)) //在同一个层次图里尽量找增广路 ans+=tans; printf("Case %d: %d\n",te,ans); } return 0;}
邻接表 436MS
#include <string.h>#include <iostream>#include <cstdio>#include <queue>using namespace std;#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) );#define RE freopen("1.in","r",stdin);#define WE freopen("output.txt","w",stdout);#define debug(x) cout<<#x<<":"<<(x)<<endl;const int maxm=1005;const int maxn=20;const int inf = 0x3f3f3f3f;struct Edge{ int v,w,next;}edge[maxm*2];int head[maxn],dis[maxn];int tol;void addEdge(int u,int v,int w){ edge[tol].v=v,edge[tol].w=w,edge[tol].next=head[u];head[u]=tol++; edge[tol].v=u,edge[tol].w=0,edge[tol].next=head[v];head[v]=tol++;}void init(){ tol=0; CLR(head,-1);}bool bfs(int s,int t){ queue<int>q; q.push(s); CLR(dis,-1); dis[s]=0; while(!q.empty()) { int u=q.front();q.pop(); for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if( dis[v]<0 && edge[i].w) { dis[v]=dis[u]+1; q.push(v); } } } return dis[t]!=-1;}int dfs(int s,int t,int low){ int flow; if(t==s) return low; for(int i=head[s];i!=-1;i=edge[i].next) { int v=edge[i].v; if(edge[i].w && (dis[v]==dis[s]+1) && (flow = dfs(v,t,min(low,edge[i].w)))) { edge[i].w -= flow; edge[i^1].w += flow; return flow; } } return 0;}int maxFlow(int s,int t){ int ans=0,tmp; while(bfs(s,t)) while(tmp=dfs(s,t,inf)) ans+=tmp; return ans;}int main(){ int t,m,n,a,b,c;// RE scanf("%d",&t); for(int te=1;te<=t;te++) { init(); scanf("%d%d",&n,&m); while(m--) { scanf("%d%d%d",&a,&b,&c); addEdge(a,b,c); } printf("Case %d: %d\n",te,maxFlow(1,n)); } return 0;}
0 0
- HDU 3549 Flow Problem 网络流入门
- HDU 3549 Flow Problem【网络流入门题】
- HDU 3549 Flow Problem (网络流入门+模板详解)
- 网络流入门题hdu3549(Flow Problem)
- HDU 3549 Flow Problem(最大流入门)
- HDU 3549 Flow Problem(最大流入门)
- HDU 3549 Flow Problem(最大流入门)
- HDU 3549 Flow Problem(网络流入门题-最大流的Ford-Fulkerson算法)
- hdu 1532 Drainage Ditches 和hdu 3549 Flow Problem 网络流入门(EK和dinic)
- HDU 3549 适合网络流入门(内含sap模板和Dinic模板)Flow Problem
- HDU3549 Flow Problem (网络流入门题)
- HDU OJ 3549 Flow Problem 【最大流入门】
- hdu 3549 Flow Problem 最大流入门 EK算法
- HDU 3549 Flow Problem【最大流入门题】【Ford-Fulkerson算法】【Dinic算法】【ISAP算法】
- hdoj 3549 Flow Problem 【最大流入门 dinic算法】
- hdoj Flow Problem 3549 (最大流入门)
- HDU 3549 Flow Problem 网络流 基础题
- HDU 3549 Flow Problem(网络流模板题)
- 思科二进制游戏 轻松掌握二进制转换
- linux安装交叉编译器
- 【算法】一道有趣的GOOGLE面试题 --【解法2】
- hdu 5060 求球与圆柱相交体积
- struts2+ajax 获取jason数据错误
- HDU 3549 Flow Problem【网络流入门题】
- WebX学习笔记1----配置环境
- POJ 1330 Nearest Common Ancestors LCA
- Ubuntu 下搭建Android开发环境
- SIFT特征提取分析
- Effective Java
- 关于浮点型的原理记录
- 几何HDU 3103
- 读书笔记-程序观点下的线性代数