• 【BZOJ 3993】【SDOI 2015】星际战争


    http://www.lydsy.com/JudgeOnline/problem.php?id=3993
    调了好长时间啊
    这道题设时间为time,那么对于m个武器从S向这m个点连容量为time*Bi的边,代表能造成的总伤害。
    对于每个武器向每个能打到的机器人连容量为无穷的边。
    对每个机器人向T连自己的装甲量Ai为容量的边。
    又因为每个机器人的装甲必须被打完,所以设机器人到T的边的下界为Ai(上下界相等)。
    从T向S连容量无穷大的边,构成无源汇上下界网络流,所以构造附加网络然后二分时间time就可以了。
    注意附加网络有一些边是走不通的,所以把那些边删掉也可以
    (删掉后和原网络没什么区别啊Σ( ° △ °|||)︴那我还讲这么偏QAQ)。
    Dinic模板打残致命伤!!!以后改数组边界的时候注意要看程序中调用数组边界的常量是否也需要改。

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define forU(i, a, b) for (int i = (a), UP = (b); i <= UP; ++i)
    #define forD(i, a, b) for (int i = (a), DOWN = (b); i >= DOWN; --i)
    using namespace std;
    
    inline double fabs(double x) {return x < 0 ? -x : x;}
    
    const int N = 55;
    const int M = N * N * 2;
    
    struct node {
    	int nxt, to; double c;
    	node(int _nxt = 0, int _to = 0, double _c = 0) : nxt(_nxt), to(_to), c(_c) {}
    } E[M];
    int cnt, point[N << 1], cur[N << 1];
    
    void ins(int u, int v, double c) {
    	E[++cnt] = node(point[u], v, c); point[u] = cnt;
    	E[++cnt] = node(point[v], u, 0); point[v] = cnt;
    }
    
    bool can[N][N];
    int q[N << 1], n, m, S, T, d[N << 1];
    double A[N], B[N];
    
    bool BFS() {
    	memset(d, 0, sizeof(int) * (T + 1));
    	int head = 0, tail = 1, u, v; q[1] = S; d[S] = 1;
    	while (head != tail) {
    		u = q[++head];
    		for (int i = point[u]; i; i = E[i].nxt)
    			if (fabs(E[i].c) > 1e-12 && !d[v = E[i].to]) {
    				d[v] = d[u] + 1;
    				q[++tail] = v;
    			}
    	}
    	return d[T];
    }
    
    double DFS(int u, double a) {
    	if (fabs(a) < 1e-12 || u == T) return a;
    	double f, flow = 0;
    	for (int &i = cur[u]; i; i = E[i].nxt)
    		if (d[E[i].to] == d[u] + 1 && fabs(f = DFS(E[i].to, min(a, E[i].c))) > 1e-12) {
    			a -= f; flow += f; E[i].c -= f; E[i ^ 1].c += f;
    			if (fabs(a) < 1e-12) break;
    		}
    	return flow;
    }
    
    double Dinic() {
    	double flow = 0;
    	while (BFS()) {
    		memcpy(cur, point, sizeof(int) * (T + 1));
    		flow += DFS(S, 100000000000000.0);
    	}
    	return flow;
    }
    
    double tot = 0;
    
    bool can2(double tim) {
    	memset(point, 0, sizeof(int) * (T + 1));
    	cnt = 1;
    	forU (i, 1, m) {
    		ins(S, i, tim * B[i]);
    		forU (j, 1, n)
    			if (can[i][j])
    				ins(i, j + m, 100000000000000.0);
    	}
    	forU (i, 1, n) ins(i + m, T, A[i]);
    	
    	return fabs(Dinic() - tot) < 1e-5;
    }
    
    int main() {
    	scanf("%d%d", &n, &m); S = n + m + 1; T = S + 1;
    	forU (i, 1, n) scanf("%lf", A + i), tot += A[i];
    	forU (i, 1, m) scanf("%lf", B + i);
    	int num;
    	double left = 0, right = 0, mid;
    	forU (i, 1, m)
    		forU (j, 1, n) {
    			scanf("%d", &num);
    			can[i][j] = num;
    		}
    	forU (i, 1, n) {
    		double fornow = 0;
    		forU (j, 1, m)
    			fornow = max(fornow, B[j]);
    		right += ceil(A[i] / fornow);
    	}
    	
    	while (right - left > 1e-5) {
    		mid = (left + right) / 2.0;
    		if (can2(mid)) right = mid;
    		else left = mid;
    	}
    	
    	printf("%lf
    ", left);
    	return 0;
    }
    
  • 相关阅读:
    netcore跨域问题与接口请求错误400
    JAVA基础
    Codeforces Round #738 (Div. 2) E.Mocha and Stars 容斥+DP
    Codeforces Round #737 (Div. 2) D. Ezzat and Grid DP+线段树优化
    牛客多校第四场 H.Convolution 数论 推式子
    51Nod-1514 美妙的序列 多项式求逆模板题
    牛客多校第4场 G.Product EGF解决排列问题
    上帝与集合的正确做法 拓展欧拉定理 欧拉函数性质
    [Codeforces Round #736 (Div. 2)](https://codeforces.com/contest/1549) E.F1 题解
    洛谷P7725 珍珠帝王蟹 分类讨论
  • 原文地址:https://www.cnblogs.com/abclzr/p/6230778.html
Copyright © 2020-2023  润新知