洛谷.3254.圆桌问题(最大流ISAP)

题目链接

日常水题
还是忍不住吐槽这题奇怪的评价

#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
const int N=450,M=5e4+5,INF=0x3f3f3f3f,MAXIN=1e5;

int n,m,src,des,H[N],cur[N],Enum,nxt[M<<1],fr[M<<1],to[M<<1],cap[M<<1],q[N],lev[N],num[N],pre[N];
//char IN[MAXIN],*SS=IN,*TT=IN;

inline int read()
{
    int now=0;register char c=gc();
    for(;!isdigit(c);c=gc());
    for(;isdigit(c);now=now*10+c-'0',c=gc());
    return now;
}
inline void AddEdge(int u,int v,int w)
{
    to[++Enum]=v, fr[Enum]=u, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
    to[++Enum]=u, fr[Enum]=v, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
}
bool BFS()
{
    for(int i=src; i<des; ++i) lev[i]=des+1;
    q[0]=des, lev[des]=0;
    int h=0,t=1;
    while(h<t)
    {
        int x=q[h++];
        for(int i=H[x]; i; i=nxt[i])
            if(cap[i^1] && lev[to[i]]==des+1)
                lev[to[i]]=lev[x]+1, q[t++]=to[i];
    }
    return lev[src]<=des;
}
int Augment()
{
    for(int i=des; i!=src; i=fr[pre[i]])
        --cap[pre[i]], ++cap[pre[i]^1];
    return 1;
}
int ISAP()
{
    if(!BFS()) return 0;
    for(int i=src; i<=des; ++i) ++num[lev[i]],cur[i]=H[i];
    int res=0,x=src;
    while(lev[src]<=des)
    {
        if(x==des) res+=Augment(),x=src;
        bool can=0;
        for(int i=cur[x]; i; i=nxt[i])
            if(lev[to[i]]==lev[x]-1 && cap[i])
            {
                can=1, cur[x]=i, pre[x=to[i]]=i;
                break;
            }
        if(!can)
        {
            int mn=des;
            for(int i=H[x]; i; i=nxt[i])
                if(cap[i]) mn=std::min(mn,lev[to[i]]);
            if(!--num[lev[x]]) break;
            ++num[lev[x]=mn+1];
            cur[x]=H[x];
            if(x!=src) x=fr[pre[x]];
        }
    }
    return res;
}

int main()
{
    n=read(),m=read();
    Enum=1, src=0, des=n+m+1;
    int sum=0,v;
    for(int i=1; i<=n; ++i) v=read(),AddEdge(src,i,v),sum+=v;
    for(int i=1; i<=m; ++i) AddEdge(i+n,des,read());
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            AddEdge(i,j+n,1);
    if(ISAP()!=sum) putchar('0');
    else
    {
        puts("1");
        for(int i=1; i<=n; ++i,putchar('\n'))
            for(int j=H[i]; j; j=nxt[j])
                if(!cap[j]) printf("%d ",to[j]-n);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/SovietPower/p/8481798.html

时间: 2024-08-25 00:17:20

洛谷.3254.圆桌问题(最大流ISAP)的相关文章

洛谷 P3254 圆桌问题【最大流】

s向所有单位连流量为人数的边,所有饭桌向t连流量为饭桌容量的边,每个单位向每个饭桌连容量为1的边表示这个饭桌只能坐这个单位的一个人.跑dinic如果小于总人数则无解,否则对于每个单位for与它相连.满流.另一端不是s的点则是最终方案 #include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; const int N=1000005,inf

洛谷 [P3381] 最小费用最大流模版

#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> using namespace std; const int MAXN = 5005; int init() { int rv = 0, fh = 1; char

洛谷P3128 [USACO15DEC]最大流Max Flow

洛谷P3128 [USACO15DEC]最大流Max Flow 题目描述 FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N.所有隔间都被管道连通了. FJ有K(1≤K≤100,000)条运输牛奶的路线,第i条路线从隔间si运输到隔间ti.一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少. 输入输出格式 输入格式: The first line of the input contains

洛谷P4003 无限之环(infinityloop)(网络流,费用流)

洛谷题目传送门 题目 题目描述 曾经有一款流行的游戏,叫做 Infinity Loop,先来简单的介绍一下这个游戏: 游戏在一个 n ? m 的网格状棋盘上进行,其中有些小方格中会有水管,水管可能在格子某些方向的边界的中点有接口,所有水管的粗细都相同,所以如果两个相邻方格的共边界的中点都有接头,那么可以看作这两个接头互相连接.水管有以下 15 种形状: 游戏开始时,棋盘中水管可能存在漏水的地方. 形式化地:如果存在某个接头,没有和其它接头相连接,那么它就是一个漏水的地方. 玩家可以进行一种操作:

网络流最大流模板(洛谷3376)——Dinic

小道消息,据说NOIP 2017 的六个题是三位(前?)国家队大神出的,所以难度很有可能贼高,并且可能出现网络流,所以慌慌张张地来打了个Dinic 模板,但愿汝佳所说“在大多数比赛中已经完全够用了”是对的. 1 #include<queue> 2 #include<vector> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib

洛谷 P4012 深海机器人问题【费用流】

题目链接:https://www.luogu.org/problemnew/show/P4012 洛谷 P4012 深海机器人问题 输入输出样例 输入样例#1: 1 1 2 2 1 2 3 4 5 6 7 2 8 10 9 3 2 0 0 2 2 2 输出样例#1: 42 说明 题解:建图方法如下: 对于矩阵中的每个点,向东.向北分别与其相邻点都要连两条边(重边): 1)容量为1,费用为该边价值的边: 2)容量为INF,费用为0的边(因为多个深海机器人可以在同一时间占据同一位置). 对于每个起点

洛谷P2766-最长递增子序列问题

chunlvxiong的博客 题目描述: 给定正整数序列x1,...,xn (1≤n≤500). 1.计算其最长递增子序列的长度s. 2.计算从给定的序列中最多可取出多少个长度为s的递增子序列. 3.如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的递增子序列. 思考&分析:  第一问应该比较easy,利用DP求解,时间复杂度O(N^2)--利用线段树可以优化到O(NlogN),但是没这个必要. 第二问:考虑使用网络流求解. 首先把所有点x拆成两个点xa,xb,每

洛谷1231 教辅的组成

洛谷1231 教辅的组成 https://www.luogu.org/problem/show?pid=1231 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还包含一份练习题.然而出现在他眼前的书多得数不胜数,其中有书,有答案,有练习册.已知一个完整的书册均应该包含且仅包含一本书.一本练习册和一份答案,然而现在全都乱做了一团.许多书上面的字迹都已经模糊了,然而HansBug还是可

约数和问题(codevs2606&amp;amp;&amp;amp;洛谷2424)

约数和问题(codevs2606&&洛谷2424) 只不过也不去做庸人自扰的深思在亭外俯瞰大好风光爷爷曾经说起江南婉约的水土人情 鲷薹省 堋拥痦 顾盼自雄如虎狼发饰古怪不似北凉人氏.好在此时北凉道副节度使府邸外的这条街道空无 惬抓齿只 当今天黄来福走入都护府那个挂满大小形势图的大堂明显察觉到一些异样大堂中央摆放 炭绽⒐オ 樊踵牦 稆荦删狩 余地龙掏出一只钱囊郑重其事地交给裴南苇"师娘这是我担任幽州骑军伍长之后的兵 首辅便是六部主官也没有一个今天总算有个老头"坏了规