[BZOJ3931][CQOI2015][網絡流]網絡吞吐量[水題]

CQOI2015送分題。(馬上省選了好緊張好緊張好緊張好緊張)

題目上已經把怎麼做說得一清二楚了。先跑最短路,只有屬於某條最短路的邊是可以走的;把它們拿出來,拆點網絡流即可。

(我這麼弱只有切這種水題了,竟然還切了一下午…… 我真是沒救了麼……)

不要隨便看代碼,不要隨便看代碼,不要隨便看代碼。因爲很重要說以說三遍

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

//Global Variables & Definitions
#define LL long long
#define MAXN 550
#define MAXM 100010
#define INF 0x3fffffff
#define REV(i) ((i) ^ 1)
#define IN(x) (x)
#define OUT(x) ((x) + 510)
#define MS(arr, x) memset(arr, x, sizeof(arr))
#define S OUT(1)
#define T IN(N)
int N, M;

void init_edge2(void);
void adde2(int, int, int);
//End Global Variables & Definitions

//Map
struct edge {
	int u, v, w, next;
} e[MAXM * 2];
int ecnt;
int h[MAXN * 2];

inline void init_edge() {
	memset(h, ecnt = -1, sizeof(h));
}

void adde(int u, int v, int w) {
	++ecnt;
	e[ecnt].u = u;
	e[ecnt].v = v;
	e[ecnt].w = w;
	e[ecnt].next = h[u];
	h[u] = ecnt;
}

queue<int> q;
int dis[MAXN * 2];
int inq[MAXN * 2];
void SPFA() {
	MS(dis, 0x3f);
	MS(inq, 0);
	
	dis[1] = 0; inq[1] = 1; q.push(1);
	while(!q.empty()) {
		int temp = q.front(); q.pop();
		inq[temp] = 0;
		int v;
		
		for(int i = h[temp];~i;i = e[i].next) if(dis[v = e[i].v] > dis[temp] + e[i].w) {
			dis[v] = dis[temp] + e[i].w;
			
			if(!inq[v]) {
				inq[v] = 1;
				q.push(v);
			}
		}
	}
	
	init_edge2();
	for(int i = 0;i <= ecnt;++i) if(dis[e[i].u] + e[i].w == dis[e[i].v]) {
		adde2(OUT(e[i].u), IN(e[i].v), INF);
	}
	
	int temp;
	for(int i = 1;i <= N;++i) {
		scanf("%d", &temp);
		adde2(IN(i), OUT(i), temp);
	}
}

#undef edge
struct edge_ {
	int v, next;
	int cap, flow;
} e2[MAXM * 4];
int ecnt2;
int h2[MAXN * 2];

void init_edge2() {
	memset(h2, ecnt2 = -1, sizeof(h2));
}

void _adde2(int u, int v, int cap) {
	++ecnt2;
	e2[ecnt2].v = v;
	e2[ecnt2].cap = cap;
	e2[ecnt2].flow = 0;
	e2[ecnt2].next = h2[u];
	h2[u] = ecnt2;
}

void adde2(int u, int v, int cap) {
	_adde2(u, v, cap);
	_adde2(v, u, 0);
}

#undef e
#undef h
#undef ecnt
#define e e2
#define h h2
#define ecnt ecnt2

bool BFS() {
	MS(dis, 0xff);
	
	dis[S] = 0; q.push(S);
	while(!q.empty()) {
		int temp = q.front(); q.pop();
		int v;
		
		for(int i = h[temp];~i;i = e[i].next) if(e[i].cap > e[i].flow) {
			if(~dis[v = e[i].v]) continue;
			
			dis[v] = dis[temp] + 1;
			q.push(v);
		}
	}
	
	return ~dis[T];
}

LL dfs(int u, int a) {
	if(u == T || a == 0) return a;
	
	LL tflow, totflow = 0;
	for(int i = h[u];~i;i = e[i].next) if(dis[e[i].v] == dis[u] + 1 && e[i].cap > e[i].flow) {
		tflow = dfs(e[i].v, min(a, e[i].cap - e[i].flow));
		e[i].flow += tflow;
		e[REV(i)].flow -= tflow;
		totflow += tflow;
		a -= tflow;
		
		if(!a) break;
	}
	
	return totflow;
}

LL Dinic() {
	LL ans = 0;
	while(BFS()) ans += dfs(OUT(1), INF);
	
	return ans;
}
//End Map

//Main Structure
inline void ir() {
	init_edge();
	freopen("network.in", "r", stdin);
	freopen("network.out", "w", stdout);
	
	scanf("%d%d", &N, &M);
	
	int aa, bb, dd;
	for(int i = 0;i < M;++i) {
		scanf("%d%d%d", &aa, &bb, &dd);
		adde(aa, bb, dd);
		adde(bb, aa, dd);
	}
}

int main() {
	ir();
	SPFA();
	
	printf("%I64d\n", Dinic());
	return 0;
}



(上面的代碼沒去freopen,而且輸出用了%I64d,交到bzoj上一定會掛。說了不要隨便貼代碼了 ╮(╯▽╰)╭)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章