• luoguP3381 【模板】最小费用最大流


    题目描述

    如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。

    输入输出格式

    输入格式:
    第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
    接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。

    输出格式:
    一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。

    输入输出样例

    输入样例#1:
    4 5 4 3
    4 2 30 2
    4 3 20 3
    2 3 20 1
    2 1 30 9
    1 3 40 5

    输出样例#1:
    50 280

    说明
    时空限制:1000ms,128M

    数据规模:
    对于30%的数据:N<=10,M<=10
    对于70%的数据:N<=1000,M<=1000
    对于100%的数据:N<=5000,M<=50000

    分析:模板题
    注意两点:1.判断时不能使用0x7f,原因是不能精准判断,只能大致估计,所以在memeset时最好使用0x33,这样在判断时的写法为dis[t]<0x33333333(8个3)
    2.记得加快读

    这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<queue>
    
    using namespace std;
    
    const int INF=0x33333333;
    const int N=1001000;
    struct node{
        int x,y,v,cost,next;
    };
    node way[N*2];
    int st[N],tot=-1;
    int n,m,s,t,flow=0,ans=0; 
    bool p[N];
    int pre[N],dis[N];  ///
    
    int in()  //快读
    {
        int t=0;
        char ch=getchar();
        while(ch>'9'||ch<'0') ch=getchar();
        while(ch>='0'&&ch<='9') t=(t<<1)+(t<<3)+ch-'0',ch=getchar();
        return t;
    }
    
    void add(int u,int w,int z,int c)
    {
        tot++;
        way[tot].x=u;way[tot].y=w;way[tot].v=z;way[tot].cost=c;way[tot].next=st[u];st[u]=tot;
        tot++;
        way[tot].x=w;way[tot].y=u;way[tot].v=0;way[tot].cost=-c;way[tot].next=st[w];st[w]=tot;
    }
    
    int spfa()
    {
        int i;
        memset(pre,0,sizeof(pre));
        memset(p,1,sizeof(p));
        memset(dis,0x33,sizeof(dis));  //花费   ////0x33
        queue<int> q;
        q.push(s);
        dis[s]=0;
        p[s]=0;
        while (!q.empty())
        {
            int r=q.front();
            q.pop();
            for (i=st[r];i!=-1;i=way[i].next)
            {
                if (way[i].v&&dis[way[i].y]>dis[r]+way[i].cost)  //
                {
                    dis[way[i].y]=dis[r]+way[i].cost;
                    pre[way[i].y]=i;  //记录一下修改来自哪条路
                    if (p[way[i].y])
                    {
                        p[way[i].y]=0;
                        q.push(way[i].y);    
                    } 
                }
            }
            p[r]=1;  ///
        }
        return dis[t]<INF;
    }
    
    void doit()
    {
        int sum,i;
        while (spfa())
        {
            sum=INF;  //增广量
            for (i=t;i!=s;i=way[pre[i]].x)  //从汇点反向增广
                sum=min(sum,way[pre[i]].v);  //流量 
            ans+=dis[t]*sum;
            flow+=sum;
            for (i=t;i!=s;i=way[pre[i]].x)
            {
                way[pre[i]].v-=sum;
                way[pre[i]^1].v+=sum;
            } 
        }
        printf("%d %d
    ",flow,ans);
        return;
    }
    
    int main()
    {
        memset(st,-1,sizeof(st));
        n=in();m=in();s=in();t=in();
        for (int i=1;i<=m;i++)
        {
            int u,w,z,c;
            u=in();w=in();z=in();c=in();
            add(u,w,z,c);
        }
        doit();
        return 0;
    } 
  • 相关阅读:
    解析json字符串
    python学习(十)文件操作方式
    python学习(九)集合
    python学习(八)内存地址及深/浅拷贝
    python学习(七)列表/字典合并、布尔型、交换变量值、列表转换字符串连接和分割
    python学习(六)字符串
    Python学习(五)字典
    python学习(四)数组,字符串,元组
    python学习(四)列表(数组)
    python学习(三)字符串格式化&strip的用法&小练习
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673633.html
Copyright © 2020-2023  润新知