hdu 4240 Route Redundancy(dinic)

28 篇文章 0 订阅

题意很别扭的的一道题,先是求最大流,再求所有可行流中的流量最大的那个流(因为该流的流量取决于该流上流量最小的那条边,正好是题意要求的),然后求其比值即可

而dinic在dfs到汇点的时候正好也可以求出上述的流大小

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<iostream>

using namespace std;

const int N = 100005;
const int inf = 99999999;

struct node{
	int v, w, nxt;
}e[N*10];

int head[N], dep[N];
int cnt, n, m, ed, st;
int maxflow;
queue<int> q;

void init()
{
	cnt = 0;
	memset( head, -1, sizeof( head ));
	maxflow = -1;
}

void add( int u, int v, int w )
{
	e[cnt].v = v;
	e[cnt].w = w;
	e[cnt].nxt = head[u];
	head[u] = cnt++;
	
	e[cnt].v = u;
	e[cnt].w = 0;
	e[cnt].nxt = head[v];
	head[v] = cnt++;
}

int bfs()
{
	while( !q.empty() )
		q.pop();
	memset( dep, 0, sizeof( dep ));
	dep[st] = 1;
	q.push(st);
	while( !q.empty() )
	{
		int u = q.front();
		q.pop();
		if( u == ed )
			return 1;
		for( int i = head[u]; ~i; i = e[i].nxt )
		{
			int v = e[i].v;
			if( e[i].w && !dep[v] )
			{
				dep[v] = dep[u] + 1;
				q.push(v);
			}
		}
	}
	return 0;
}

int dinic( int u, int minflow )
{
	if( u == ed )
	{
		maxflow = max( maxflow, minflow);
		return minflow;
	}
	int tmp = 0;
	for( int i = head[u]; ~i; i = e[i].nxt )
	{
		int v = e[i].v;
		if( e[i].w && dep[v] == dep[u] + 1 )
		{
			int flow = dinic( v, min(minflow - tmp, e[i].w));
			e[i].w -= flow;
			e[i^1].w += flow;
			tmp += flow;
			if( tmp == minflow )
				return tmp;
		}
	}
	return tmp;
}

int main()
{
	int tot;
	scanf("%d", &tot);
	int dat;
	while( tot-- )
	{
		scanf("%d%d%d%d%d", &dat, &n, &m, &st, &ed);
		init();
		int u, v, w;
		while(m--)
		{
			scanf("%d%d%d", &u, &v, &w);
			add(u, v, w);
		}
		int ans = 0, tmp;
		maxflow = 0;
		while( bfs() )
		{
			tmp = dinic(st, inf);
			ans += tmp;
		}
		printf("%d %.3f\n", dat, (double)ans * 1.0 / (double) maxflow);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值