zoukankan      html  css  js  c++  java
  • [bzoj2330][SCOI2011]糖果

    题目大意:要求给 $n$ 个人分配糖果,记第 $i$ 个人分配到的糖果数为 $S_i$,要求 $S_i > 0$。另外有 $k$ 个限制,每个限制形如 $X A B(X in [1,5])$,分别表示:

    $X=1,S_A = S_B$

    $X=2,S_A < S_B$

    $X=3,S_A geq S_B$

    $X=4,S_A > S_B$

    $X=5,S_A leq S_B$

    求至少需要多少糖果?

    题解:差分约束。

    对于差分不等式,$a − b leq c$,建一条 $b$ 到 $a$ 的权为 $c$ 的边,求的是最短路,得到的是最大值,负环表示无解。

    对于差分不等式,$a − b geq c$,建一条 $b$ 到 $a$ 的权为 $c$ 的边,求的是最长路,得到的是最小值,正环表示无解。

    因为求的是最小值,将不等式转化为 $a − b geq c$ 的形式求最长路即可。注意判自环。

    卡点:1.最开始从$0$向各个点连一条权值为$1$的边来跑,$TLE+WA$,改成每个点跑一遍就$AC$了

    C++ Code:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #define maxn 100010
    using namespace std;
    const long long inf = 9223372036854775807;
    int n, k, x, a, b;
    
    int head[maxn], cnt;
    struct Edge {
    	int to, nxt, w;
    } e[maxn << 1];
    void add(int a, int b, int c) {
    	e[++cnt] = (Edge) {b, head[a], c}; head[a] = cnt;
    }
    
    long long d[maxn];
    int num[maxn];
    bool vis[maxn];
    queue <int> q;
    void spfa(int rt) {
    	q.push(rt);
    	while (!q.empty()) {
    		int u = q.front(); q.pop();
    		vis[u] = false;
    		for (int i = head[u]; i; i = e[i].nxt) {
    			int v = e[i].to;
    			if (d[v] < d[u] + e[i].w) {
    				d[v] = d[u] + e[i].w;
    				num[v]++;
    				if (num[v] >= n) {
    					puts("-1");
    					exit(0);
    				}
    				if (!vis[v]) {
    					vis[v] = true;
    					q.push(v);
    				}
    			}
    		}
    	}
    }
    int main() {
    	scanf("%d%d", &n, &k);
    	for (int i = 0; i < k; i++) {
    		scanf("%d%d%d", &x, &a, &b);
    		switch (x) {
    			case 1: {
    				add(a, b, 0);
    				add(b, a, 0);
    				break;
    			}
    			case 2: {
    				if (a == b) {
    					puts("-1");
    					return 0;
    				}
    				add(a, b, 1);
    				break;
    			}
    			case 3: {
    				add(b, a, 0);
    				break;
    			}
    			case 4: {
    				if (a == b) {
    					puts("-1");
    					return 0;
    				}
    				add(b, a, 1);
    				break;
    			}
    			default: add(a, b, 0);
    		}
    	}
    	for (int i = 1; i <= n; i++) d[i] = 1;
    	for (int i = 1; i <= n; i++) {
    		spfa(i);
    	}
    	long long ans = 0;
    	for (int i = 1; i <= n; i++) ans += d[i];
    	printf("%lld
    ", ans);
    	return 0;
    } 
    

      

  • 相关阅读:
    leetcode 175 Combine Two Tables join用法
    spark学习及环境配置
    html表格设计
    免费的论文查重网站
    php利用msqli访问数据库并实现分页,
    php利用href进行页面传值的正确姿势
    php+mysql时报错:Unknown column '' in 'field list'解决方案
    使用XMLHttpRequest解析json
    用自定义的函数将gps转换为高德坐标
    WeakHashMap回收时机
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9498272.html
Copyright © 2011-2022 走看看