[BZOJ3931] [CQOI2015]网络吞吐量 && 网络流

多么裸的一个网络流 可是我爆0了

inf要开的非常非常大才行 每一个数据都非常非常大 QAQ 长教训了 

先从n跑一遍最短路 然后从1开始宽搜 最短路径上的边才连入图中 然后每个点拆点 跑最大流就行了 

这么仁慈 这么裸 这么水的网络流 我居然爆0了 

果然像我这样的人最好早点滚粗 

 

#include
#include
#include
#include
#include
#include
#include
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const int MAXN = 500 * 2;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
const LL inf = 1LL * MAXM * 1000000000;
int n, m, val[MAXN+10], S, T;
int cnt, cho[MAXN+10];
struct Node {
	int u, v, next;
	LL c;
} ;
struct ISAP {
	int gap[MAXN*2+10], d[MAXN*2+10];
	int adj[MAXN*2+10], ecnt;
	int n, m, s, t;
	Node Edge[MAXM*4+10];
	void init() {
		memset(adj, -1, sizeof(adj));
	}
	void addedge(int u, int v, LL c) {
		Node &e = Edge[ecnt];
		e.v = v; e.u = u; e.c = c; e.next = adj[u];
		adj[u] = ecnt++;
		m = ecnt;
	}
	void add(int u, int v, LL c) {
		addedge(u, v, c); addedge(v, u, 0);
	}
	void init_dis() {
		queue  q;
		memset(d, -1, sizeof(d));
		memset(gap, 0, sizeof(gap));
		d[t] = 0; q.push(t); cnt = 1;
		while(!q.empty()) {
			int u = q.front(); q.pop();
			gap[d[u]]++;
			for(int i = adj[u]; ~i; i = Edge[i].next) {
				int v = Edge[i].v;
				if(d[v] == -1) d[v] = d[u] + 1, q.push(v), cnt++;
			}
		}
	}
	LL aug(int u, LL inc) {
		int mindis = n-1;
		LL Inc = 0;
		if(u == t) return inc;
		for(int i = adj[u]; ~i; i = Edge[i].next) {
			Node &e = Edge[i];
			int v = e.v;
			LL c = e.c;
			if(c) {
				if(d[v] == d[u] - 1) {
					LL del = min(1LL * c, inc - Inc);
					del = aug(v, del);
					Inc += del;
					Edge[i].c -= del;
					Edge[i^1].c += del;
					if(d[s] >= n) return Inc;
					if(inc == Inc) return Inc;
				}
				mindis = min(mindis, d[v]);
			}
		}
		if(!Inc) {
			gap[d[u]]--;
			if(gap[d[u]] == 0) d[s] = n;
			d[u] = mindis + 1;
			gap[d[u]]++;
		}
		return Inc;
	}
	LL Maxflow(int _s, int _t, int _n) {
		n = _n; s = _s; t = _t;
		LL Flow = 0;
		init_dis();
		n = cnt;
		while(d[s] < n) 
			Flow += aug(s, inf);
		return Flow;
	}
} sap;
Node edge[MAXM*2+10];
int Adj[MAXN+10], Ecnt;
bool vis[MAXN+10];
LL dis[MAXN+10];
queue  q;
void addedge(int u, int v, int wt) {
	Node &e = edge[Ecnt];
	e.v = v; e.c = wt; e.next = Adj[u]; Adj[u] = Ecnt++;
} ;
void SPFA() {
	for(int i = 1; i <= n; i++) dis[i] = inf;
	dis[n] = 0; q.push(n);
	while(!q.empty()) {
		int u = q.front(); q.pop();
		vis[u] = false;
		for(int i = Adj[u]; ~i; i = edge[i].next) {
			int v = edge[i].v, wt = edge[i].c;
			if(dis[v] > dis[u] + wt) {
				dis[v] = dis[u] + wt;
				if(!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
}
void Build_Graph() {
	q.push(1); 
	memset(vis, 0, sizeof(vis));
	vis[1] = true;
	while(!q.empty()) {
		int u = q.front(); q.pop();
		for(int i = Adj[u]; ~i; i = edge[i].next) {
			int v = edge[i].v, wt = edge[i].c;
			if(dis[v] == dis[u] - wt) {
				sap.add(u+n, v, INF);
				if(!vis[v]) vis[v] = true, q    .push(v);
			}
		}
	}
}
int main() {
	memset(Adj, -1, sizeof(Adj));
	sap.init();
	SF("%d%d", &n, &m);
	S = 1; T = n;
	for(int i = 1; i <= m; i++) {
		int u, v, wt;
		SF("%d%d%d", &u, &v, &wt);
		addedge(u, v, wt);
		addedge(v, u, wt);
	}
	for(int i = 1; i <= n; i++) SF("%d", &val[i]);
	SPFA();
	Build_Graph();
	for(int i = 2; i < n; i++) sap.add(i, i+n, val[i]);
	sap.add(1, n+1, inf);
	LL ans = sap.Maxflow(S, T, n*2-1);
	cout << ans;
}


你可能感兴趣的:(网络流,BZOJ)