zoukankan      html  css  js  c++  java
  • luogu 1344 追查坏牛奶(最小割)

    第一问求最小割。 第二问求割边最小的最小割。

    我们直接求出第二问就可以求出第一问了。

    对于求割边最小,如果我们可以把每条边都附加一个1的权值,那么求最小割是不是会优先选择1最少的边呢。

    但是如果直接把边的权值+1,这样求得的最小割就不是原来的最小割了,那是因为1会对原来的容量产生影响。

    如果把每条边的权值都乘以一个很大的常数,再加上附加权值1,这样求出的最小割是不是显然也是原图的最小割呢。

    那么最终的答案除以这个常数就是最小割的容量,最终的答案模这个常数就是最小割的最小割边数。

    # include <cstdio>
    # include <cstring>
    # include <cstdlib>
    # include <iostream>
    # include <vector>
    # include <queue>
    # include <stack>
    # include <map>
    # include <set>
    # include <cmath>
    # include <algorithm>
    using namespace std;
    # define lowbit(x) ((x)&(-x))
    # define pi acos(-1.0)
    # define eps 1e-7
    # define MOD 1024523
    # define INF 1e16
    # define mem(a,b) memset(a,b,sizeof(a))
    # define FOR(i,a,n) for(int i=a; i<=n; ++i)
    # define FO(i,a,n) for(int i=a; i<n; ++i)
    # define bug puts("H");
    # define lch p<<1,l,mid
    # define rch p<<1|1,mid+1,r
    # define mp make_pair
    # define pb push_back
    typedef pair<int,int> PII;
    typedef vector<int> VI;
    # pragma comment(linker, "/STACK:1024000000,1024000000")
    typedef long long LL;
    int Scan() {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    void Out(int a) {
        if(a<0) {putchar('-'); a=-a;}
        if(a>=10) Out(a/10);
        putchar(a%10+'0');
    }
    const int N=35;
    //Code begin...
    
    struct Edge{int p, next; LL w;}edge[4005];
    int head[N], cnt=2, s, t, vis[N];
    queue<int>Q;
    
    void add_edge(int u, int v, LL w){
        edge[cnt].p=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++;
        edge[cnt].p=u; edge[cnt].w=0; edge[cnt].next=head[v]; head[v]=cnt++;
    }
    int bfs(){
        int i, v;
        mem(vis,-1);
        vis[s]=0; Q.push(s);
        while (!Q.empty()) {
            v=Q.front(); Q.pop();
            for (i=head[v]; i; i=edge[i].next) {
                if (edge[i].w>0 && vis[edge[i].p]==-1) {
                    vis[edge[i].p]=vis[v] + 1;
                    Q.push(edge[i].p);
                }
            }
        }
        return vis[t]!=-1;
    }
    LL dfs(int x, LL low){
        int i;
        LL a, temp=low;
        if (x==t) return low;
        for (i=head[x]; i; i=edge[i].next) {
            if (edge[i].w>0 && vis[edge[i].p]==vis[x]+1){
                a=dfs(edge[i].p,min(edge[i].w,temp));
                temp-=a; edge[i].w-=a; edge[i^1].w += a;
                if (temp==0) break;
            }
        }
        if (temp==low) vis[x]=-1;
        return low-temp;
    }
    int main ()
    {
        int n, m, u, v, w;
        LL P=10000000;
        scanf("%d%d",&n,&m); s=1; t=n;
        FOR(i,1,m) scanf("%d%d%d",&u,&v,&w), add_edge(u,v,(LL)w*P+1);
        LL sum=0;
        while (bfs()) sum+=dfs(s,INF);
        printf("%lld %lld
    ",sum/P,sum%P);
        return 0;
    }
    View Code
  • 相关阅读:
    【2】KNN:约会对象分类器
    Android学习笔记_69_android 支付宝之网页支付和快捷支付
    风吹过你走的那一刻,带走了你最后的足印,抹拭了我唯一追寻的方向
    The connection to adb is down, and a severe error has occured.
    RSA加密算法
    Android动画之translate(位移动画)
    Android学习笔记_68_ android 9patch 图片
    android:TableLayout表格布局详解
    Android 中 shape 图形的使用
    Android学习笔记_67_Android MyCrashHandler 中异常处理 UncaughtExceptionHandler
  • 原文地址:https://www.cnblogs.com/lishiyao/p/6820636.html
Copyright © 2011-2022 走看看