LGOJ1344 追查坏牛奶

Description

link

题意概述:给一张图,每条边有边权,求让点 \(1\) 和点 \(n\) 不连通的“最小破坏边权和” 和 “在此基础上的最小破坏边数”

边数 \(\leq 1000\) ,点数 \(\leq 32\)

Solution

\[Begin\]

其实看出来这个可以用最小割做挺显然的

然后第二问的做法就有点点技巧了

我们把图中的每一条边的边权 \(w_i\) 转化成 \(a \times w_i+1\)

其中\(a\) > \(1000\)

然后我们跑最大流,求得的 \(ans/a\) 就是最小割,然后 \(ans \% a\) 就是边数

这里特别好理解的

\[Finish\]

Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
    inline int read()
    {
        int res=0,f=1; char k;
        while(!isdigit(k=getchar())) if(k=='-') f=-1;
        while(isdigit(k)) res=res*10+k-'0',k=getchar();
        return res*f;
    }
    const int N=1e4+10,M=1e5+10;
    struct node{int nxt,to,lim;}e[M<<1];
    int head[N],dep[N],ans,s,t,cnt=1,n,m,a=1002;
    inline void add(int u,int v,int w)
    {
        e[++cnt].nxt=head[u],e[cnt].lim=w; e[cnt].to=v;
        return head[u]=cnt,void();
    }
    queue<int>q;
    inline bool bfs()
    {
        memset(dep,-1,sizeof(dep)); dep[s]=0;
        while(q.size()) q.pop(); q.push(s);
        while(!q.empty())
        {
            int fr=q.front(); q.pop();
            for(int i=head[fr];i;i=e[i].nxt)
            {
                int tr=e[i].to;
                if(dep[tr]==-1&&e[i].lim) dep[tr]=dep[fr]+1,q.push(tr);
            }
        }
        return dep[t]!=-1;
     }
    inline int dfs(int now,int in)
    {
        if(now==t) return in; int out=0;
        for(int i=head[now];i&&in;i=e[i].nxt)
        {
            int tr=e[i].to;
            if(e[i].lim&&dep[tr]==dep[now]+1)
            {
                int res=dfs(tr,min(in,e[i].lim));
                in-=res; out+=res; e[i].lim-=res;
                e[i^1].lim+=res;
            }
        } if(!out) dep[now]=-1; return out;
    }
    signed main()
    {
        n=read(),m=read(); s=1,t=n;
        for(int i=1,u,v,w;i<=m;++i)
        {
            u=read(); v=read(); w=read();
            add(u,v,w*a+1);  add(v,u,0);
        }
        while(bfs()) ans+=dfs(s,1e17);
        printf("%lld %lld\n",ans/a,ans%a);
        return 0;
    }
}
signed main(){return yspm::main();} 

没怎么压行,应该挺可读的

原文地址:https://www.cnblogs.com/yspm/p/12358402.html

时间: 2024-10-14 04:50:35

LGOJ1344 追查坏牛奶的相关文章

追查坏牛奶(最大流)

进入今天的正题,追查坏牛奶 思想的话不会人家的玄学求最小割的边数,于是自己想了个神奇的乱搞,先求出最大流,即最小割,然后枚举每条边看是否完全属于割集,然后将其永久去掉 然后将整个输出即可 #include<bits/stdc++.h> using namespace std; #define ll long long const int N=100010; const ll INF=0x7ffffffff; ll m,n,s,t,pre[N],head[N],cnt=1,last[N],dep

USACO 4.4.2 追查坏牛奶 oj1341 网络流最小割问题

描述 Description 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这件事的时候,有三聚氰胺的牛奶已经进入了送货网.这个送货网很大,而且关系复杂.你知道这批牛奶要发给哪个零售商,但是要把这批牛奶送到他手中有许多种途径.送货网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输牛奶.在追查这些有三聚氰胺的牛奶的时候,有必要保证它不被送到零售商手里,所以必须使某些运输卡车停止运输,但是停止每辆卡车都会有一定的经济损失.你的

USACO Section 4.4 追查坏牛奶Pollutant Control

http://www.luogu.org/problem/show?pid=1344 题目描述 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这件事的时候,有三聚氰胺的牛奶已经进入了送货网.这个送货网很大,而且关系复杂.你知道这批牛奶要发给哪个零售商,但是要把这批牛奶送到他手中有许多种途径.送货网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输牛奶.在追查这些有三聚氰胺的牛奶的时候,有必要保证它不被送到零售商手里,所以必须

洛谷 P1344 [USACO4.4]追查坏牛奶Pollutant Control

题目描述 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这件事的时候,有三聚氰胺的牛奶已经进入了送货网.这个送货网很大,而且关系复杂.你知道这批牛奶要发给哪个零售商,但是要把这批牛奶送到他手中有许多种途径.送货网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输牛奶.在追查这些有三聚氰胺的牛奶的时候,有必要保证它不被送到零售商手里,所以必须使某些运输卡车停止运输,但是停止每辆卡车都会有一定的经济损失.你的任务是,在保证坏牛奶

【COGS】894. 追查坏牛奶

http://cojs.tk/cogs/problem/problem.php?pid=894 题意:n个点m条边的加权网络,求最少边数的按编号字典序最小的最小割.(n<=32, m<=1000) #include <bits/stdc++.h> using namespace std; typedef long long ll; struct Gr { static const int N=33, M=1005, oo=~0u>>1; struct E { int n

luogu 1344 追查坏牛奶(最小割)

第一问求最小割. 第二问求割边最小的最小割. 我们直接求出第二问就可以求出第一问了. 对于求割边最小,如果我们可以把每条边都附加一个1的权值,那么求最小割是不是会优先选择1最少的边呢. 但是如果直接把边的权值+1,这样求得的最小割就不是原来的最小割了,那是因为1会对原来的容量产生影响. 如果把每条边的权值都乘以一个很大的常数,再加上附加权值1,这样求出的最小割是不是显然也是原图的最小割呢. 那么最终的答案除以这个常数就是最小割的容量,最终的答案模这个常数就是最小割的最小割边数. # includ

[USACO4.4]追查坏牛奶Pollutant Control

https://www.luogu.org/problemnew/show/P1344 这道题很容易就可以看出是最小割=最大流. 但是要求出要割几条边就有些毒瘤了. ↓为废话 但orzn*inf后,蒟蒻我还是没有想出怎么回事 犹豫好久后,还是悄咪咪点开了题解......... ↑为废话 原来有一个经典的套路: 只需建图时将边权w=w*a+1(w为本来的边权,a为大于1000的数),这样我们能求得最大流ans,则最小割的值为ans/a,割的边数为ans%a. 因为最小割的边集中有w1+w2+w3…

【题解】Luogu P1344 [USACO4.4]追查坏牛奶Pollutant Control

原题传送门 看到这种题,应该一眼就能知道考的是最小割 没错这题就是如此简单,跑两遍最大流(最小割=最大流),一次边权为题目所给,一次边权为1 还有一种优化,优化后只需跑一次最大流,把每条边的权值改成w*MOD+1(MOD为常数,珂以取八位质数233) 答案为maxflow/MOD和maxflow%MOD 基础版本 #include <bits/stdc++.h> #define N 40 #define M 2005 #define inf 0x3f3f3f3f #define getchar

记录一次追查server死机&amp; 登录异常情况

linux 服务器死机了,于是追查原因. 查看boot.log [email protected]:/var/log$ less boot.log 看不出异常 显示开机信息 [email protected]:/var/log$ less dmesg 区别;(未明) /var/log/boot.log --- System boot log /var/log/dmesg --- print or control the kernel ring buffer /var/log/messages看看