最大流总结

准备开始学习最大流。

持续更新。

(hdu zoj poj vj 都挂了 还怎么刷题啊……)

326. Perspective

题意:一个小组有n个队伍1~n,每场比赛一个队伍赢,一个队伍输,现在已知每个队伍i都已经赢了Wi场比赛,同时知道每个队伍还需要打Ri场比赛,包括组内和组外,同时知道组内还剩下的比赛场数,Aij表示i和j还需要打几场比赛,Aij=Aji,∑(j:1~n)Aij <= Ri

问题是队伍1能否成为小组获胜场数最多的,可以并列第一。

题解:首先让队伍1赢得所有的比赛,其他队伍输掉所有组外的比赛。然后建图最大流。

/*
 * 建一个源点 然后对于每一场比赛为一个点 从源点到比赛连边,权值为比赛的总分数
 * 比赛这个点和比赛的两个队伍分别连边 权值大于等于比赛最大分数即可
 * 每个队伍到汇点连一条边 权值应为该队伍和1队分数的差值(如果分数大于1队,应该直接输出no
 * 走一遍最大流 如果答案是所有比赛的分数和就可以满足要求
 */
#include <bits/stdc++.h>

const int N = 1000;
const int M = 1000000;
const int INF = 1 << 30;
struct Edge {
    int to, next, w;
} edge[M];
int head[N], cntE;
int src, sink;
int pre[N], cur[N], dis[N], gap[N];
int que[N], open, tail;
void addedge(int u, int v, int w) {
    edge[cntE].to = v;
    edge[cntE].w = w;
    edge[cntE].next = head[u];
    head[u] = cntE++;
    edge[cntE].to = u;
    edge[cntE].w = 0;
    edge[cntE].next = head[v];
    head[v] = cntE++;
}
void BFS() {
    int i, u, v;
    memset(gap, 0, sizeof(gap));
    memset(dis, -1, sizeof(dis));
    open = tail = 0;
    que[open] = sink;
    dis[sink] = 0;
    while (open <= tail) {
        u = que[open++];
        for (i = head[u]; i != -1; i = edge[i].next) {
            v = edge[i].to;
            if (edge[i].w != 0 || dis[v] != -1) continue;
            que[++tail] = v;
            ++gap[dis[v] = dis[u] + 1];
        }
    }
}
int sap(int n) { //编号从1开始 1~n
    int i, v, u, flow = 0, aug = INF;
    int flag;
    BFS();
    gap[0] = 1;
    for (i = 1; i <= n; i++) cur[i] = head[i];
    u = pre[src] = src;
    while (dis[src] < n) {
        flag = 0;
        for (int j = cur[u]; j != -1; j = edge[j].next) {
            v = edge[j].to;
            if (edge[j].w > 0 && dis[u] == dis[v] + 1) {
                flag = 1;
                if (edge[j].w < aug) aug = edge[j].w;
                pre[v] = u;
                u = v;
                if (u == sink) {
                    flow += aug;
                    while (u != src) {
                        u = pre[u];
                        edge[cur[u]].w -= aug;
                        edge[cur[u] ^ 1].w += aug;
                    }
                    aug = INF;
                }
                break;
            }
            cur[u] = edge[j].next;
        }
        if (flag) continue;
        int mindis = n;
        for (int j = head[u]; j != -1; j = edge[j].next) {
            v = edge[j].to;
            if (edge[j].w > 0 && mindis > dis[v]) {
                mindis = dis[v];
                cur[u] = j;
            }
        }
        if (--gap[dis[u]] == 0) break;
        ++gap[dis[u] = mindis + 1];
        u = pre[u];
    }
    return flow;
}

int w[N], r[N], a[N][N];
int main() {
    int n;
    while (~scanf("%d", &n)) {
        for (int i = 1; i <= n; ++i) scanf("%d", w+i);//每个队伍已经赢了多少场比赛
        for (int i = 1; i <= n; ++i) scanf("%d", r+i);//每个队伍还可以打多少场比赛,包括本组和外组
        for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) scanf("%d", &a[i][j]);//本组剩余比赛情况
        w[1] += r[1]; //贪心 让本队全赢
        bool fg = false;
        for (int i = 2; i <= n; ++i) if (w[i] > w[1]) { fg = true; break; }
        if (fg) { puts("NO"); continue; }
        src = 1;
        int cnt = n+1;
        int sum = 0;
        cntE = 0;
        memset(head, -1, sizeof head);
        for (int i = 2; i <= n; ++i) for (int j = i; j <= n; ++j) {
            if (a[i][j] <= 0) continue;
            sum += a[i][j];
            addedge(src, cnt, a[i][j]);
            addedge(cnt, i, INF);
            addedge(cnt, j, INF);
            cnt++;
        }
        sink = cnt;
        for (int i = 2; i <= n; ++i) addedge(i, sink, w[1]-w[i]);
        if (sap(sink) == sum) puts("YES");
        else puts("NO");
    }
    return 0;
}

时间: 2024-12-19 19:17:33

最大流总结的相关文章

对IO流的操作(文件大小,拷贝,移动,删除)

import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.SequenceInputStream; class LjyFileClass { /*LjyFileClass工具类使用需知: * * 1.计算

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

Java学习之IO流三

1.从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中(高效流) 1 /** 2 * 1.从键盘接收两个文件夹路径,把其中一个文件夹中(包含内容)拷贝到另一个文件夹中 3 * @author vanguard 4 * 5 */ 6 public class Demo01 { 7 public static void main(String[] args) { 8 //键盘输入两个文件夹路径 9 Scanner sc = new Scanner(System.in); 1

标准文档流

标准流指的是在不使用其他的与排列和定位相关的特殊CSS规则时,各种元素的排列规则.HTML文档中的元素可以分为两大类:行内元素和块级元素.       1.行内元素不占据单独的空间,依附于块级元素,行内元素没有自己的区域.它同样是DOM树中的一个节点,在这一点上行内元素和块级元素是没有区别的.       2.块级元素总是以块的形式表现出来,并且跟同级的兄弟块依次竖直排列,左右自动伸展,直到包含它的元素的边界,在水平方向不能并排.盒子在标准流中的定位原则margin控制的是盒子与盒子之间的距离,

Properties-转换流-打印流-序列化和反序列化-Commons-IO工具类

一.Properties 类(java.util)     概述:Properties 是一个双列集合;Properties 属于map的特殊的孙子类;Properties 类没有泛型,properties集合的key和value都是固定的数据类型(String),该集合提供了一些特有的方法存取值,是唯一一个可以与IO流相结合的集合; 定义:public class Properties extends Hashtable

14. 流、文件和IO

前言 InputStream/OutStream流用来处理设备之间的数据传输 Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类型.对象.本地化字符集等等. 一个流可以理解为一个数据的序列.输入流表示从一个源读取数据,输出流表示向一个目标写数据. 流按操作数据分为两种:字节流与字符流 按流向分为:输入流(InputStream)和输出流(OutputStream) Java 为 I/O 提供了强大的而

videojs集成--播放rtmp流

之前说到已经把流推送过来了,这时候就可以使用videojs来进行显示播放. 首先要先有一个文件,那就是video-js.swf 因为,这种播放方式html已经不能很好的进行播放了,需要用到flash来播放,videojs在这个地方就用到了这个. 代码就是下面这样. 里面一些细节注释都有. 重点就是看<video>标签里面的内容 [html] view plain copy <!DOCTYPE html> <html lang="en"> <he

快速入门系列--WCF--06并发限流、可靠会话和队列服务

这部分将介绍一些相对深入的知识点,包括通过并发限流来保证服务的可用性,通过可靠会话机制保证会话信息的可靠性,通过队列服务来解耦客户端和服务端,提高系统的可服务数量并可以起到削峰的作用,最后还会对之前的事务知识做一定补充. 对于WCF服务来说,其寄宿在一个资源有限的环境中,为了实现服务性能最大化,需要提高其吞吐量即服务的并发性.然而在不进行流量控制的情况下,并发量过多,会使整个服务由于资源耗尽而崩溃.因此为相对平衡的并发数和系统可用性,需要设计一个闸门(Throttling)控制并发的数量. 由于

Java中I/O流之数据流

Java 中的数据流: 对于某问题:将一个 long 类型的数据写到文件中,有办法吗?    转字符串 → 通过 getbytes() 写进去,费劲,而且在此过程中 long 类型的数需要不断地转换. 现在,Java 中的数据流能够很好的解决这个问题(不需要转换,直接写进去) 1. DataInputStream 与 DataOutputStream 分别继承自 InputStream.OutputStream, 它属于处理流,需要分别套接在 InputStream.OutputStream 类

费用流(bzoj 3130)

Description Alice和Bob在图论课程上学习了最大流和最小费用最大流的相关知识.    最大流问题:给定一张有向图表示运输网络,一个源点S和一个汇点T,每条边都有最大流量.一个合法的网络流方案必须满足:(1)每条边的实际流量都不超过其最大流量且非负:(2)除了源点S和汇点T之外,对于其余所有点,都满足该点总流入流量等于该点总流出流量:而S点的净流出流量等于T点的净流入流量,这个值也即该网络流方案的总运输量.最大流问题就是对于给定的运输网络,求总运输量最大的网络流方案. 上图表示了一