zoukankan      html  css  js  c++  java
  • [SDOI 2009] 晨跑

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=1877

    [算法]

            不难看出,第一问要求的是最大流,第二问求的是最小费用最大流

            注意建图时要将每个点拆成入点和出点,防止经过同一个地点多次

    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 1010
    #define MAXM 40010
    const int inf = 2e9;
    
    struct edge
    {
            int to,w,cost,nxt;
    } e[MAXM << 1];
    
    int i,n,m,tot,a,b,c,S,T,ans1,ans2;
    int pre[MAXN << 1],dist[MAXN << 1],incf[MAXN << 1],head[MAXN << 1];
    
    template <typename T> inline void read(T &x)
    {
            int f = 1; x = 0;
            char c = getchar();
            for (; !isdigit(c); c = getchar())
            {
                    if (c == '-') f = -f;
            }
            for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
            x *= f;
    }
    inline void addedge(int u,int v,int w,int cost)
    {
            tot++;
            e[tot] = (edge){v,w,cost,head[u]};
            head[u] = tot;
            tot++;
            e[tot] = (edge){u,0,-cost,head[v]};
            head[v] = tot;
    }
    
    inline bool spfa()
    {
            int i,l,r,u,v,w,cost;
            static int q[MAXN << 1];
            static bool inq[MAXN << 1];
            for (i = 1; i <= 2 * n; i++)
            {
                    dist[i] = inf;
                    incf[i] = inf;
                    inq[i] = false;
            }
            q[l = r = 1] = S;
            inq[S] = true;
            pre[S] = 0;
            dist[S] = 0;
            while (l <= r)
            {
                    u = q[l];
                    l++;
                    inq[u] = false;
                    for (i = head[u]; i; i = e[i].nxt)
                    {
                            v = e[i].to;
                            w = e[i].w;
                            cost = e[i].cost;
                            if (w && dist[u] + cost < dist[v]) 
                            {
                                    dist[v] = dist[u] + cost;
                                    incf[v] = min(incf[u],w);
                                    pre[v] = i;
                                    if (!inq[v])
                                    {
                                            inq[v] = true;
                                            q[++r] = v;
                                    }
                            }
                    }    
            }        
            if (dist[T] != inf) return true;
            else return false;
    }
    inline void update()
    {
            int pos,x = T;
            while (x != S)
            {
                    pos = pre[x];
                    e[pos].w -= incf[T];
                    e[pos ^ 1].w += incf[T];
                    x = e[pos ^ 1].to;
            }
            ans1 += incf[T];
            ans2 += dist[T] * incf[T];
    }
    
    int main() 
    {
            
            read(n); read(m);
            tot = 1;
            addedge(1,n + 1,inf,0);
            addedge(n,2 * n,inf,0);
            for (i = 2; i < n; i++) addedge(i,i + n,1,0);
            for (i = 1; i <= m; i++)
            {
                    read(a); read(b); read(c);
                    addedge(a + n,b,1,c);        
            }
            S = 1; T = 2 * n;        
            while (spfa()) update();
            printf("%d %d
    ",ans1,ans2);
            
            return 0;
        
    }
  • 相关阅读:
    Microsoft SQL Server 自定义函数整理大全 [转]
    eclipse将android项目生成apk并且给apk签名
    Android实现对图片的缩放、剪切、旋转、存储
    Android 之 ProgressDialog用法介绍
    Android中Path类的lineTo方法和quadTo方法画线的区别
    Android仿微信二维码扫描
    Android中Bitmap,byte[],Drawable相互转化
    hibernate基础之无法自动创建表总结
    Android获取短信验证码
    Android之常见问题集锦Ⅰ
  • 原文地址:https://www.cnblogs.com/evenbao/p/9492938.html
Copyright © 2011-2022 走看看