`

【最大流+dinic+二分】北大 poj 2455 Secret Milking Machine

阅读更多

/* THE PROGRAM IS MADE BY PYY */
/*----------------------------------------------------------------------------//
    Copyright (c) 2012 panyanyany All rights reserved.

    URL   : http://poj.org/problem?id=2455
    Name  : 2455 Secret Milking Machine

    Date  : Sunday, February 12, 2012
    Time Stage : 4 hours

    Result:
9799773	panyanyany
2455
Accepted	1900K	282MS	C++
3943B	2012-02-12 21:46:03

Test Data :
7 9 2
1 2 2
2 3 5
3 7 5
1 4 1
4 3 1
4 5 7
5 7 1
1 6 3
6 7 3


Review :
TLE 4个小时,原来是模板有问题,好多细节理解不到位啊!
//----------------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>


#define MEM(a, v)		memset (a, v, sizeof (a))	// a for address, v for value
#define max(x, y)		((x) > (y) ? (x) : (y))
#define min(x, y)		((x) < (y) ? (x) : (y))

#define INF		(0x3f3f3f3f)
#define MAXN	(204)

#define DB	/##/

struct EDGE {
	int u, v, c, n ;
};

int		n, p, t, eCnt ;
int		level[MAXN], q[MAXN], vertex[MAXN] ;
EDGE	net[MAXN*MAXN*10] ;

struct E {
	int u, v, c ;
} ed[MAXN*MAXN*10] ;

inline void init()
{
//	MEM (map, INF) ;
}

inline void insert (int u, int v, int c)
{
	net[eCnt].u = u ;
	net[eCnt].v = v ;
	net[eCnt].c = c ;
	net[eCnt].n = vertex[u] ;
	vertex[u] = eCnt++ ;

	net[eCnt].u = v ;
	net[eCnt].v = u ;
	net[eCnt].c = c ;
	net[eCnt].n = vertex[v] ;
	vertex[v] = eCnt++ ;
}

void makegraph (int lim)
{
	int i ;
	MEM(vertex, -1) ;
	eCnt = 0 ;
	for (i = 1 ; i <= p ; ++i)
		if (ed[i].c <= lim)
			insert (ed[i].u, ed[i].v, 1) ;
}

void out ()
{
	int i, j ;
	for (i = 1 ; i <= n ; ++i)
	{
		for (j = 1 ; j <= n ; ++j)
			printf ("%d ", net[i].c) ;
		puts ("") ;
	}
}

int dinic (const int beg, const int end)
{
	int sum, u, v, head, tail, i ;
	int e ;
	sum = 0 ;

	while (true)
	{
		MEM (level, -1) ;
		head = tail = 0 ;
		q[tail++] = beg ;
		level[beg] = 0 ;

		while (head < tail)
		{
			u = q[head++] ;
			for (e = vertex[u] ; e != -1 ; e = net[e].n)
			{
				v = net[e].v ;
				if (net[e].c > 0 && -1 == level[v])
				{
					level[v] = level[u] + 1 ;
					if (end == v)
					{
						head = tail ;
						break ;
					}
					q[tail++] = v ;
				}
			}
		}

		if (-1 == level[end])
			break ;
		
		u = beg ;
		tail = 0 ;

		while (true)
		{
			if (end == u)
			{
				int flow = INF, qbreak ;
				for (i = 0 ; i < tail ; ++i)
				{
					e = q[i] ;
					// flow >= net[e].c 会消耗更多时间
					if (flow > net[e].c)
					{
						flow = net[e].c ;
						qbreak = i ;
					}
				}
				sum += flow ;
				for (i = 0 ; i < tail ; ++i)
				{
					e = q[i] ;
					net[e].c -= flow ;
					net[e^1].c += flow ;
				}

				// 这样写超时:
				// e = q[qbreak] ;
				// tail = qbreak + 1 ;
				u = net[q[qbreak]].u ;
				tail = qbreak ;
			}

			for (e = vertex[u] ; e != -1 ; e = net[e].n)
				if (net[e].c > 0 && level[u]+1 == level[net[e].v])
					break ;

			if (-1 == e)
			{
				if (tail == 0)
					break ;
				level[net[q[--tail]].v] = -1 ;
				u = net[q[tail]].u ;
			}
			else
			{
				u = net[e].v ;
				q[tail++] = e ;
			}
		}
	}
	return sum ;
}

int main()
{
	int i ;
	int ans, tmpans, low, hig, mid ;
	while (scanf ("%d%d%d", &n, &p, &t) != EOF)
	{
		init();
		hig = 0 ;
		low = 1000000 ;
		for (i = 1 ; i <= p ; ++i)
		{
			scanf ("%d%d%d", &ed[i].u, &ed[i].v, &ed[i].c) ;
			low = min(ed[i].c, low) ;
			hig = max(ed[i].c, hig) ;
		}

		while (low <= hig)
		{
			mid = (low + hig) / 2 ;
			makegraph (mid) ;
			if ((tmpans = dinic(1, n)) >= t)
			{
				ans = mid ;
				hig = mid - 1 ;
			}
			else
				low = mid + 1 ;
		}
		printf ("%d\n", ans) ;
	}
	return 0 ;
}

0
0
分享到:
评论

相关推荐

    网络流最大流Dinic算法代码

    最大流的Dinic算法,时间复杂度O(EV^2),代码简单而高效

    最大流Dinic算法(最高标号法)原论文

    [Din70]Algorithm for solution of a problem of maximum flow in a network with power estimation.pdf 最大流最高标号法(DINIC法)的论文原文

    POJ3308-Paratroopers 【Dinic算法求最大流】

    【二分图顶点覆盖-&gt;最小割-&gt;最大流-&gt;Dinic算法求解】 解题报告+AC代码 http://hi.csdn.net/!s/WKVPR0 ----&gt; 我的所有POJ解题报告 http://blog.csdn.net/lyy289065406/article/details/6642573

    最大流的Dinic算法与SAP算法的实现

    最大流问题在图论和网络优化中占有重要地位,它旨在寻找从源点到汇点在网络中的最大流量,而不会超过任何边的容量限制。在这个问题的求解中,Dinic算法和Shortest Augmenting Path (SAP)算法是两种高效的方法。 ...

    最大网络流Dinic算法

    最大网络流问题在图论和运筹学中占有重要地位,它主要研究在一个有向图中,从源点到汇点能通过的最大流量。Dinic算法是由苏联计算机科学家E. A. Dinic于1970年提出的,是一种解决此类问题的有效算法。该算法基于层的...

    图论- 网络流- 最大流- Dinic 算法.rar

    Dinic于1970年提出的求解最大流问题的有效算法,它的主要特点是基于层的概念和增广路径的思想。下面我们将深入探讨Dinic算法的基本原理和步骤。 1. **初始化**:首先定义源点s和汇点t,将所有边的容量设为边上的...

    DINIC最大流算法

    用DINIC方法实现最大流算法,亲测可以运行!VS2008环境下编辑运行通过!

    最大流dinic算法

    Dinic算法的基本思路: 1.根据残量网络计算层次图。 2.在层次图中使用DFS进行增广直到不存在增广路 3.重复以上步骤直到无法增广

    网络流Dinic

    Dinic算法是一种高效的求解最大流问题的方法,通过构建层次化的残余网络并利用DFS寻找增广路径来不断更新流量,最终找到网络的最大流。通过对算法的深入理解与实践,可以帮助我们在实际问题中更好地应用这一算法。

    网络流dinic模板

    网络流dinic模板,非本人原创。网络流dinic模板,非本人原创

    Dinic.rar_Dinif2.m_dinic_最大流_最大流算法_最大网络流

    本文将详细介绍Dinic算法,这是一种高效的求解网络最大流的算法。 首先,我们要理解什么是最大流。在网络流问题中,我们有一个带权重的有向图,其中每个边代表一个可以传输流量的连接,每条边都有一个容量限制。...

    非递归邻接表DINIC最大流模板

    ### 非递归邻接表DINIC最大流算法详解 #### 一、引言 在图论中,寻找网络中的最大流量是一项经典问题。其中,DINIC算法(由Yefim Dinitz于1970年提出)是一种高效解决这类问题的方法。本文将详细介绍一个非递归版本...

    dinic网络流算法

    Dinic于1970年提出,是一种求解网络最大流问题的高效算法。在图论和运筹学中,网络流问题涉及到在一个有向图中从一个源节点到一个汇点传输“流量”,同时满足容量限制和供需平衡的条件。Dinic算法以其优秀的性能和...

    最大流模板.cpp dinic

    最大流模板.cpp dinic

    POJ2195-Going Home【费用流】

    【标题】"POJ2195-Going Home" 是一道来自北京大学在线判题系统POJ的编程题目,主要考察的是运用费用流算法解决实际问题的能力。这道题的中文名称是“回家”,通过题目我们可以推测它可能涉及到路径规划或者资源分配...

    acm pku spoj sgu 经典 图论题解题报告

    poj2723 2-sat验证,二分答案 poj2455 dinic (ek会超时) hdu1689 求最小奇数环 poj2391 isap最快,dinic不减枝会超时 poj2455 isap 最快(ek会超时) poj2832 并查集边的计算 sgu218 hcraft 二分图匹配验证 二分答案

    最大流DInic算法(链式前向星)

    给师弟师妹们讲网络流Dinic算法与可行流用到的讲义,感觉还是不错,分享一下~

    Dinic多路增广pascal源码

    Dinic多路增广pascal源码 poj 1273格式

    network-flow:最大流的 Dinic 算法的 C++ 实现

    最大流的 Dinic 算法的 C++ 实现。 以下是操作摘要: FlowNetwork f(n, m) :具有 n 个顶点(0 到 n-1)和 m 个有向边的新网络, f.add(x, y, c) :添加从节点 x 到节点 y 的有向边,容量为 c, f.flow(s, t) :...

Global site tag (gtag.js) - Google Analytics