****OJ - 1**7 B***d (费用流)

本文介绍了一种利用费用流算法解决某国防御系统瘫痪问题的方法。通过将每条边的等级视为流量,等级上限视为容量,提高等级的花费视为费用,将问题转化为寻找最小割的问题。特别注意,此问题涉及无向图,需添加反向边。最终,通过费用流算法求得最优防御策略下敌国所需成本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

****OJ - 1**7 B***d (费用流)

题意

某国防御系统需要保证节点1和节点n保持联通,每条路有一个防卫等级的属性,初始都为0,最高限制为maximax_imaxi,每提高一级需要花费costicost_icosti,敌国每破坏一条路都要花费该路的等级那么多的成本,该国国防预算F,问最优防御策略下敌国需要多少钱才能使得该国防御系统瘫痪(使得1节点和n节点不连通)

思路

这题怎么看出来是网络流呢?我们可以把每条边的等级看成流量,每条边的等级上限看成容量,提高一级的花费就是费用了。每条路径破坏的最低成本就是该路径上等级最低的边。所以我们可以用费用流求该路径上的最小的边(找增广路的过程)。如果预算不足,那么就只能把预算平摊到该路径上的所有边。其实如果预算充足,最后求到的就是最小割。需要注意的是这题是无向图,一定要加反向的边,虽然防御联络的时候只会从1走到n,但是谁能保证题目不把边反着给呢?我这么wa了20发,疯狂在找自己费用流所谓不存在的bug,还好凉凉把我点醒了。比赛的时候因为G题的no response,卡死了G 的特判没空写这题(估计有空也是死在无向图这个坑上,毕竟做到的网络流题目基本都是有向图,我会想当然)。

因为官方重现没有放出,所以对题目进行了和谐处理,如果官方重现出了我就回来把屏蔽去掉(不鸽的话)

这可能是我最后一篇题解博客了,EC之前没有遗憾了

代码

#include <iostream>
#include <vector>
#include <cstring>
#include <deque>

using namespace std;
struct edge{
    long long from;
    long long to;
    long long flow;
    long long cap;
    long long cost;
    long long nxt;
    edge(long long f,long long t,long long ca,long long co,long long n):from(f),to(t),cap(ca),cost(co),nxt(n){
        flow=0;
    }
    edge(){}
};
long long egs[1005];
vector<edge> edges;
void addedge(long long f,long long t,long long ca,long long co){
    edges.emplace_back(f,t,ca,co,egs[f]);
    egs[f]=edges.size()-1;
    edges.emplace_back(t,f,0,-co,egs[t]);
    egs[t]=edges.size()-1;
}
long long dis[1005];
long long pre[1005];
long long flower[1005];
bool vis[1005];
long long total;
long long bellmanford(long long s,long long t)
{
    memset(dis,0x3f,sizeof dis);
    memset(vis,0,sizeof vis);
    memset(pre,-1,sizeof pre);
    memset(flower,0,sizeof flower);
    dis[s]=0;
    flower[s]=0x3f3f3f3f3f3f3f3f;
    deque<long long> qq;
    qq.push_back(s);
    vis[s]=true;
    while(!qq.empty())
    {
        long long now=qq.front();
        qq.pop_front();
        for(long long i=egs[now];i!=-1;i=edges[i].nxt)
        {
            if(edges[i].cap-edges[i].flow>0 && dis[edges[i].to]>dis[now]+edges[i].cost)
            {
                dis[edges[i].to]=dis[now]+edges[i].cost;
                pre[edges[i].to]=i;
                flower[edges[i].to]=min(flower[now],edges[i].cap-edges[i].flow);
                if(!vis[edges[i].to])
                {
                    if((!qq.empty()) && dis[edges[i].to]<dis[qq.front()])
                        qq.push_front(edges[i].to);
                    else
                        qq.push_back(edges[i].to);
                    vis[edges[i].to]=true;
                }
            }
        }
        vis[now]=false;
    }
    return flower[t];
}
long long mfmc(long long s,long long t,long long c){
    long long maxflow=0;
    long long mincost=0;
    long long nowflow=0;
    nowflow=bellmanford(s,t);
    while(nowflow>0){//直接把nowflow=bellmanford(s,t)放进来在oj上好像会死循环不知道为啥
        if(nowflow*dis[t]+mincost<c){
            maxflow+=nowflow;
            mincost+=dis[t]*nowflow;
            long long now=t;
            while(now!=s){
                edges[pre[now]].flow+=nowflow;
                edges[pre[now]^1].flow-=nowflow;
                now=edges[pre[now]].from;
            }
        } else{
            maxflow+=(c-mincost)/dis[t];//预算不足就平摊到整个路径上去使得最小值最大
            break;
        }
        nowflow=bellmanford(s,t);
    }
    return maxflow;
}
int main() {
    long long n, m, f;
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m >> f;
    memset(egs, -1, sizeof egs);
    edges.clear();
    total = n;
    for (long long i = 0; i < m; i++) {
        long long a, b, c, d;
        cin >> a >> b >> c >> d;
        addedge(a, b, c, d);
        addedge(b, a, c, d);//加了这句话就过了,死在无向图20发
    }
    cout << mfmc(1, n, f) << "\n";//除了加了预算限制外就是裸的费用流
    return 0;
}

感谢我校最强银牌图论选手女装凉

### Java 编译与运行 OJ 系统中 `.class` 文件不存在解决方案 #### 1. 检查源代码路径和编译命令 确保在本地环境中使用的源代码路径以及编译命令正确无误。如果是在Eclipse或其他IDE中开发,则需确认项目结构设置合理,源文件位于正确的目录下[^1]。 ```bash javac -d . HelloWorld.java ``` 上述命令表示将编译后的`.class`文件放置于当前工作目录(`.`),并指定要编译的Java源文件为`HelloWorld.java`。 #### 2. 验证类名定义准确性 检查是否存在拼写错误或大小写不匹配的情况。例如,在给定的例子中: ```java // 错误版本 System.out.println("Hello World"); // 正确版本应改为如下所示: System.out.printLn("Hello World"); ``` 注意区分字母大小写及方法名称书写规范性[^3]。 #### 3. 处理多文件依赖关系 当涉及多个相互关联的Java源文件时,务必保证所有必要的`.java`文件都已成功编译,并且生成的目标`.class`文件存在于预期位置。特别是对于嵌套内部类的情形,可能还需要额外处理其对应的`.class`文件命名规则变化问题[^4]。 #### 4. 清除缓存重新构建项目 有时由于环境配置不当或者残留旧版编译产物的影响,可能会导致新修改未能生效。此时建议清理整个项目的临时数据后再试一次完整的编译程。 #### 5. 调整OJ平台提交方式 部分在线评测系统(OJ)对上传代码有特定的要求,比如某些情况下只允许直接粘贴纯文本形式的源码而非附件压缩包等形式;另外还需留意是否有关于入口函数签名等方面的特殊规定。 #### 6. 排查输入/输出相关异常 针对涉及到文件读写的场景,应当仔细审查所使用的I/O API调用逻辑及其参数传递情况,防止因资源未关闭等原因引发潜在隐患[^2]。 #### 7. 定位具体报错信息 面对诸如“找不到符号”的提示时,应该依据具体的上下文线索去定位实际发生的位置,进而针对性地修正相应变量声明等问题[^5]。 ```java BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); String line; while ((line = reader.readLine()) != null){ System.out.println(line); } reader.close(); ``` 以上代码展示了如何安全地从标准输入获取字符串直至结束标志出现为止,同时记得释放占用的外部连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值