养花(搜索+流)

链接:https://ac.nowcoder.com/acm/contest/5758/G
来源:牛客网

小明是一个魔法师,他有n棵植物,所有植物排成一排,植物的初始高度为数组h,小明有一些强迫症,他想
让植物的高度都恰好达到k,小明有m瓶药水,但药水分为4种:
1.选择一棵高度为a0的植物变为b0高度的植物
2.选择一棵高度在[a1,a2]区间内的植物变为b1高度的植物
3.选择一棵高度为a1的植物变为[b1, b2]区间内某一高度的植物
4.选择一棵高度在[a1,a2]区间内的植物变为[b1,b2]区间内某一高度的植物
由于每瓶药水有C瓶库存,小明想知道他最多让多少棵植物高度达到k
输入描述:
输入数据第一行是t,表示数据的组数,接下来每组数据输入n,m,k,
接下来一行输入n个数,分别是每棵植物的高度h[i](1 <= h[i] < k),
接下来m行开头的两个数字为op和c表示药水是哪一种和该种药水有几瓶,输入如下
若 op=1,则接下来两个整数 a0,b0,意义如上文所述。
若 op=2,则接下来三个整数 a1,a2,b1,意义如上文所述。
若 op=3,则接下来三个整数 a1,b1,b2,意义如上文所述。
若 op=4,则接下来四个整数 a1,a2,b1,b2,意义如上文所述。
数据保证,所有 1 <= a0,b0,a1,b1,a2,b2 <= k
(t <= 10,n <= 1e4,m <= 300,k <= 100,c <=1e6)
输出描述:
输出一个整数,表示最多有多少颗植物能生涨到k。
示例1
输入
复制
1
5 4 5
1 1 1 1 1
1 3 1 3
1 3 3 2
1 3 2 5
4 1 1 1 4 5
输出
复制
4

#include <bits/stdc++.h>
 
#define ll long long
using namespace std;
 
const int maxn = 100;
const int mod = 1e9 + 7;
 
ll qp(ll a, ll n, ll mod = ::mod) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}
 
const int MAX_V = 2000 + 10;
const int INF = 0x3f3f3f3f;
 
//用于表示边的结构体(终点,流量,反向边)
struct edge {
    int to;
    ll cap;
    int rev;
};
 
vector<edge> G[MAX_V];    //图的邻接表表示
int level[MAX_V];    //顶点到源点的距离标号
int iter[MAX_V];    //当前弧
 
void add(int from, int to, ll cap) {
//    cerr << from << " " << to << " " << cap << endl;
    G[from].push_back((edge) {to, cap, (int) G[to].size()});
    G[to].push_back((edge) {from, 0, (int) G[from].size() - 1});
}
 
//计算从源点出发的距离标号
void bfs(int s) {
    memset(level, -1, sizeof(level));
    queue<int> que;
    level[s] = 0;
    que.push(s);
    while (!que.empty()) {
        int v = que.front();
        que.pop();
        for (int i = 0; i < G[v].size(); i++) {
            edge &e = G[v][i];
            if (e.cap > 0 && level[e.to] < 0) {
                level[e.to] = level[v] + 1;
                que.push(e.to);
            }
        }
    }
}
 
//通过DFS寻找增广路
ll dfs(int v, int t, ll f) {
    if (v == t) return f;
    for (int &i = iter[v]; i < G[v].size(); i++) {
        edge &e = G[v][i];
        if (e.cap > 0 && level[v] < level[e.to]) {
            ll d = dfs(e.to, t, min(f, e.cap));
            if (d > 0) {
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}
 
//求解从s到t的最大流
ll max_flow(int s, int t) {
    ll flow = 0;
    for (;;) {
        bfs(s);
        if (level[t] < 0) return flow;
        memset(iter, 0, sizeof(iter));
        ll f;
        while ((f = dfs(s, t, INF)) > 0) flow += f;
    }
}
 
int main(int argc, char *argv[]) {
    int TT;
    scanf("%d", &TT);
    for (int kase = 1; kase <= TT; ++kase) {
        int n, m, k;
        scanf("%d%d%d", &n, &m, &k);
        int S = 0;
        int tot = k;
        vector<int> tmp(n);
        for (int i = 0; i < n; ++i) {
            scanf("%d", &tmp[i]);
        }
        sort(tmp.begin(), tmp.end());
        int pre = tmp[0], tt = 1;
        for (int i = 1; i < n; ++i) {
            if (pre == tmp[i]) {
                tt++;
            } else {
                add(S, pre, tt);
                pre = tmp[i];
                tt = 1;
            }
        }
        add(S, pre, tt);
        for (int i = 0; i < m; ++i) {
            int op;
            scanf("%d", &op);
            if (op == 1) {
                int tx, a0, b0;
                scanf("%d%d%d", &tx, &a0, &b0);
                tx = min(tx, n);
                add(a0, b0, tx);
            } else if (op == 2) {
                int tx, a1, a2, b1;
                scanf("%d%d%d%d", &tx, &a1, &a2, &b1);
                tx = min(tx, n);
                add(++tot, b1, tx);
                for (int j = a1; j <= a2; ++j) add(j, tot, tx);
            } else if (op == 3) {
                int tx, a1, b1, b2;
                scanf("%d%d%d%d", &tx, &a1, &b1, &b2);
                tx = min(tx, n);
                add(a1, ++tot, tx);
                for (int j = b1; j <= b2; ++j) add(tot, j, tx);
            } else {
                int tx, a1, a2, b1, b2;
                scanf("%d%d%d%d%d", &tx, &a1, &a2, &b1, &b2);
                tx = min(tx, n);
                int tot1 = ++tot;
                int tot2 = ++tot;
                add(tot1, tot2, tx);
                for (int j = a1; j <= a2; ++j) add(j, tot1, tx);
                for (int j = b1; j <= b2; ++j) add(tot2, j, tx);
            }
        }
        printf("%lld\n", max_flow(0, k));
        for (int i = 0; i <= tot; ++i) {
            G[i].clear();
        }
    }
    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智家居养花系统的硬件连接图可能因产品设计和开发而异,但一般包括以下几个主要部分: 1. 植物传感器:用于检测土壤湿度、温度、光照强度等参数,通常需要连接到主控制器或中央处理器。 2. 智能水泵:用于自动浇水,需要与传感器和主控制器连接,以接收来自传感器的信号并执行浇水指令。 3. 智能灯光:用于模拟日照,提供光照条件,需要与传感器和主控制器连接。 4. 主控制器/中央处理器:用于控制整个系统,包括接收传感器数据、执行浇水和灯光控制指令等。通常需要与各个硬件模块连接,包括植物传感器、智能水泵和智能灯光。 5. 电源:用于为各个硬件模块提供电力供应,通常需要在主控制器或中央处理器旁边加一个电源接口。 下面是一个简单的硬件连接图,仅供参考: ``` +-----+ +------------+ | | | | | | | 智能灯光 | | | | | | | +------------+ | | |主控制器+----+ +------------+ | | | | | | | 智能水泵 | | | | | | | +------------+ | | | | +------------+ | | | | | | | 植物传感器 | | | | | +-----+ +------------+ ``` 在这个连接图中,主控制器连接到三个硬件模块:智能灯光、智能水泵和植物传感器。植物传感器通过感应土壤湿度、温度和光照强度等参数,将数据反馈给主控制器。主控制器根据传感器数据,执行浇水和灯光控制指令,从而实现智能养花系统的自动化管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值