洛谷·[网络流24题]太空飞行计划问题

初见安~这里是传送门:洛谷P2762 太空飞行计划

洛谷·[网络流24题]太空飞行计划问题_第1张图片

Sol

这个题老鬼畜了……其实就是读入格式很恶心。

具体做法其实跑一个最大流就好了,明显是一个匹配问题。

直接贴代码吧【懒……但也是真的水。

#include
#include
#include
#include
#include
#include
#define maxn 500
#define maxm 200005
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
bool flag; char ch;
int read() {
	int x = 0, f = 1, ch = getchar();
	while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
	while(isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
	return x * f;
}

struct edge {int to, w, nxt;} e[maxm];
int head[maxn], k = 0;
void add(int u, int v, int w) {
	e[k] = {v, w, head[u]}; head[u] = k++;
	e[k] = {u, 0, head[v]}; head[v] = k++;
}

int d[maxn], S, T;
queue q;
bool bfs() {
	memset(d, 0, sizeof d); while(q.size()) q.pop();
	q.push(S); d[S] = 1;
	while(q.size()) {
		register int u = q.front(), v; q.pop(); 
		for(int i = head[u]; ~i; i = e[i].nxt) {
			v = e[i].to;
			if(e[i].w && !d[v]) {
				q.push(v), d[v] = d[u] + 1;
				if(v == T) return true;
			}
		}
	}
	return false;
}

int Dinic(int u, int flow) {
	if(u == T) return flow;
	register int rest = flow, k;
	for(int i = head[u], v; ~i && rest; i = e[i].nxt) {
		v = e[i].to; 
		if(e[i].w && d[v] == d[u] + 1) {
			k = Dinic(v, min(rest, e[i].w));
			if(!k) d[v] = 0;
			e[i].w -= k, e[i ^ 1].w += k;
			rest -= k;
		}
	}
	return flow - rest;
}

int n, m, sum = 0; 
signed main() {
	memset(head, -1, sizeof head);
	n = read(), m = read(); S = 0, T = n + m + 1;
	for(int i = 1, x; i <= n; i++) {//oh,这恶心的读入……而且你还需要看懂在干什么
		x = read(); sum += x; add(S, i, x);//连边,只给x元保证不会亏
		char tools[10000];
		memset(tools,0,sizeof tools);
		cin.getline(tools,10000);
		int ulen=0,tool;
		while (sscanf(tools+ulen,"%d",&tool)==1) {
			add(i, tool + n, INF);//连边,匹配
    		if (tool==0) ulen++;
   	 		else while (tool) {
       		    tool/=10;
            	ulen++;
        	}
  			ulen++;
		}
	}
	for(int i = 1, x; i <= m; i++) x = read(), add(i + n, T, x);//连边,仪器开销。
	
	register int flow, ans = 0;
	while(bfs()) while(flow = Dinic(S, INF)) ans += flow;//最大流保证每个实验的仪器开销一定满流,除非会亏
	for(int i = 1; i <= n; i++) if(d[i]) printf("%d ", i);
	puts("");
	for(int i = n + 1; i <= n + m; i++) if(d[i]) printf("%d ", i - n);//找匹配	
	printf("\n%d\n", sum - ans);
	return 0;
}

咕咕咕了好久的一篇文章……

迎评:)
——End——

你可能感兴趣的:(网络流,网络流24题,最大流)