【网络流EK算法&压入重标记算法】POJ 1459
2012-01-15 17:10
351 查看
这里需要加上超级源点和超级汇点,分别是n和n+1,然后用EK求最大流,因为EK的复杂度是O(V*E*E),所以时间很慢,网络流还有其他更优化的算法,但暂时不懂,学会了再做一遍比较一下效率。。。这里的输入有一点点恶心,用sscanf分离数字和符号
EK算法:625ms
push_relabel算法:188ms
EK算法:625ms
#define MIN INT_MIN #define MAX INT_MAX #define N 110 int min(int a,int b){return a>b?b:a;} int c ; int f ; int pre ; int res ; int n; int EK(int s,int t){ int i,j; queue<int> qq; memset(f,0,sizeof(f)); int ans = 0; while(1){ memset(res,0,sizeof(res)); res[s] = MAX; pre[s] = -1; qq.push(s); while(!qq.empty()){ int x = qq.front(); qq.pop(); for(i=0;i<=t;i++){ if(!res[i] && f[x][i] < c[x][i]){ qq.push(i); pre[i] = x; res[i] = min(res[x],c[x][i] - f[x][i]); } } } if(res[t] == 0)break; int k = t; while(pre[k] != -1){ f[pre[k]][k] += res[t]; f[k][pre[k]] -= res[t]; k = pre[k]; } ans += res[t]; } return ans; } int main(){ int np,nc,m; while(scanf("%d%d%d%d",&n,&np,&nc,&m) != -1){ int s = n,t = n+1; int i,j; memset(c,0,sizeof(c)); char ss[30]; for(i=0;i<m;i++){ int u,v,w; scanf("%s",ss); sscanf(ss,"(%d,%d)%d",&u,&v,&w); c[u][v] += w; } for(i=0;i<np;i++){ int u,w; scanf("%s",ss); sscanf(ss,"(%d)%d",&u,&w); c[s][u] += w; } for(i=0;i<nc;i++){ int v,w; scanf("%s",ss); sscanf(ss,"(%d)%d",&v,&w); c[v][t] += w; } printf("%d\n",EK(s,t)); } return 0; }
push_relabel算法:188ms
#define MIN INT_MIN #define MAX INT_MAX #define N 110 int min(int a,int b){return a>b?b:a;} int c ;//残留容量 int ef ;//顶点余流 int h ;//顶点高度 int n; int push_relabel(int s,int t){ int i,j; int ans = 0; memset(h,0,sizeof(h)); h[s] = t+1;//源点初始高度 memset(ef,0,sizeof(ef)); ef[s] = MAX;//源点初始余流 queue<int> qq; qq.push(s); while(!qq.empty()){ int u = qq.front(); qq.pop(); for(i=0;i<=t;i++){ int p; int v = i; if(c[u][v]<ef[u])p = c[u][v]; else p = ef[u]; if(p>0 && (u==s || h[u] == h[v] +1)){ c[u][v] -= p; c[v][u] += p; if(v==t)ans+=p;//如果到达了汇点,就将流值加入到最大流中 ef[u] -= p; ef[v] += p; if(v!=s && v!=t)qq.push(v);//只有既不是源点也不是汇点才进队 } } //如果不是源点且仍有余流,则重标记高度再进队。 //这里只是简单的将高度增加了一个单位,也可以像上面所说的一样赋值为最低的相邻顶点的高度高一个单位 if(u!= s && u!=t && ef[u]>0) { h[u]++; qq.push(u); } } return ans; } int main(){ int np,nc,m; while(scanf("%d%d%d%d",&n,&np,&nc,&m) != -1){ int s = n,t = n+1; int i,j; memset(c,0,sizeof(c)); char ss[30]; for(i=0;i<m;i++){ int u,v,w; scanf("%s",ss); sscanf(ss,"(%d,%d)%d",&u,&v,&w); c[u][v] += w; } for(i=0;i<np;i++){ int u,w; scanf("%s",ss); sscanf(ss,"(%d)%d",&u,&w); c[s][u] += w; } for(i=0;i<nc;i++){ int v,w; scanf("%s",ss); sscanf(ss,"(%d)%d",&v,&w); c[v][t] += w; } printf("%d\n",push_relabel(s,t)); } return 0; }
相关文章推荐
- ACM: 网络流 图论 poj 1459
- poj&nbsp;1459&nbsp;power&nbsp;network(网络流&nbsp;sa…
- poj 1459 Power Network 网络流初步,增广路算法,主要是建图麻烦
- 【POJ 1273 Drainage Ditches】& 网络流 & Dinic 算法
- POJ 1459 PowerNetwork 多源点网络流入门(EK算法求最大流)
- POJ 1459 ZOJ 1734 Power Network dinic 算法 网络流
- [Poj 1459] 网络流(一) {基本概念与算法}
- poj&nbsp;1459&nbsp;power&nbsp;network(网络流&nbsp;di…
- POJ 1459 网络流算法(EK)
- POJ 3835 Columbus's bargain (最短路径 spfa 算法)
- poj 1459 多源汇网络流 ISAP
- poj 1459 网络流isap和EK的比较
- poj 3281 Dining 【图论-网络流-最大流-EK&Ford-Fulkerson】
- poj 1459 Power Network 【图论-网络流-最大流-EK】
- [poj] 3468 A Simple Problem with Integers [线段树][区间加&求和][懒标记]
- ACM: 匈牙利算法 图论题 poj 3020
- JVM-GC算法_复制算法&&标记/整理算法
- POJ 1459 Power Network(网络流—最大流)
- poj 1459 多源点网络流入门题
- Power Network (poj 1459 网络流)