(还是不熟 |好难啊


HDU1532

最大流 裸题

Edmonds_Karp算法(bfs)

#include<bits/stdc++.h>
#define debug printf("!");
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;


int m;
int g[220][220],pre[220];int bfs(int st,int ed)
{
    for(int i=1;i<=m;i++)pre[i]=-1;
    int u,w=inf;
    queue<int>que;
    que.push(st);pre[st]=0;
    while(!que.empty())
    {
        u=que.front();que.pop();
        if(u==ed)break;
        for(int i=1;i<=m;i++)
        {
            if(pre[i]==-1&&g[u][i]>0)
            {
                pre[i]=u;
                w=min(w,g[u][i]);
                que.push(i);
            }
        }
    }
    if(pre[ed]==-1)return 0;
    return w;
}

int E_K(int st,int ed)
{
    int w,sum=0;
    while(w=bfs(st,ed))
    {
        int u=ed;
        while(u!=st)
        {
            g[pre[u]][u]-=w;
            g[u][pre[u]]+=w;
            u=pre[u];
        }
        sum+=w;
    }
    return sum;
}


int main()
{
    int n,i,j,k,u,v,w;
    while(~scanf("%d%d",&n,&m))
    {
        memset(g,0,sizeof(g));

        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            g[u][v]+=w;
        }
        printf("%d\n",E_K(1,m));
    }
}

Dinic算法 是E_K算法的优化 可以快一些 (bfs+dfs)

#include<bits/stdc++.h>
#define debug printf("!");
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;


int m;
int g[220][220],dep[220];

bool bfs(int st,int ed)
{
    for(int i=1;i<=m;i++)dep[i]=-1;
    int u;
    queue<int>que;
    que.push(st);dep[st]=0;
    while(!que.empty())
    {
        u=que.front();que.pop();
        for(int i=1;i<=m;i++)
        {
            if(dep[i]==-1&&g[u][i]>0)
            {
                dep[i]=dep[u]+1;
                if(i==ed)return 1;
                que.push(i);
            }
        }
    }
    return dep[ed]!=-1;
}

int dfs(int st,int ed,int lim)
{
    if(!lim||st==ed)return lim;
    int w=0,d;
    for(int i=1;i<=m;i++)
    {
        if(dep[i]==dep[st]+1&&g[st][i]>0&&(d=dfs(i,ed,min(g[st][i],lim))))
        {
            g[st][i]-=d;
            g[i][st]+=d;
            w+=d;
            lim-=d;
            if(!lim)break;
        }
    }
    return w;
}

int Dinic(int st,int ed)
{
    int sum=0;
    while(bfs(st,ed))sum+=dfs(st,ed,inf);
    return sum;
}


int main()
{
    int n,i,j,k,u,v,w;
    while(~scanf("%d%d",&n,&m))
    {
        memset(g,0,sizeof(g));

        for(i=1;i<=n;i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            g[u][v]+=w;
        }
        printf("%d\n",Dinic(1,m));
    }
}

LOJ网络流 24 题」搭配飞行员 (第一题

#include<bits/stdc++.h>
#define debug printf("!");
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;


int n,m;
int g[110][110],dep[110];

bool bfs(int st,int ed)
{
    for(int i=0;i<=n;i++)dep[i]=-1;
    int u;
    queue<int>que;
    que.push(st);dep[st]=0;
    while(!que.empty())
    {
        u=que.front();que.pop();
        for(int i=1;i<=n;i++)
        {
            if(dep[i]==-1&&g[u][i]>0)
            {
                dep[i]=dep[u]+1;
                if(i==ed)return 1;
                que.push(i);
            }
        }
    }
    return dep[ed]!=-1;
}

int dfs(int st,int ed,int lim)
{
    if(!lim||st==ed)return lim;
    int w=0,d;
    for(int i=0;i<=n;i++)
    {
        if(dep[i]==dep[st]+1&&g[st][i]>0&&(d=dfs(i,ed,min(g[st][i],lim))))
        {
            g[st][i]-=d;
            g[i][st]+=d;
            w+=d;
            lim-=d;
            if(!lim)break;
        }
    }
    return w;
}

int Dinic(int st,int ed)
{
    int sum=0;
    while(bfs(st,ed))sum+=dfs(st,ed,inf);
    return sum;
}


int main()
{
    int i,j,k,u,v;
    scanf("%d%d",&n,&m);
//    scanf("%d",&k);
    for(i=1;i<=m;i++)g[0][i]=1;
    for(i=m+1;i<=n;i++)g[i][n+1]=1;
    n++;
//    while(k--)
    while(~scanf("%d%d",&u,&v))
    {
//        scanf("%d%d",&u,&v);
        g[u][v]=1;

    }
    printf("%d\n",Dinic(0,n));
}

洛谷P2756飞行员配对方案问题

#include<bits/stdc++.h>
#define debug printf("!");
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;


int n,m;
int g[110][110],dep[110];

bool bfs(int st,int ed)
{
    for(int i=0;i<=n;i++)dep[i]=-1;
    int u;
    queue<int>que;
    que.push(st);dep[st]=0;
    while(!que.empty())
    {
        u=que.front();que.pop();
        for(int i=1;i<=n;i++)
        {
            if(dep[i]==-1&&g[u][i]>0)
            {
                dep[i]=dep[u]+1;
                if(i==ed)return 1;
                que.push(i);
            }
        }
    }
    return dep[ed]!=-1;
}

int dfs(int st,int ed,int lim)
{
    if(!lim||st==ed)return lim;
    int w=0,d;
    for(int i=0;i<=n;i++)
    {
        if(dep[i]==dep[st]+1&&g[st][i]>0&&(d=dfs(i,ed,min(g[st][i],lim))))
        {
            g[st][i]-=d;
            g[i][st]+=d;
            w+=d;
            lim-=d;
            if(!lim)break;
        }
    }
    return w;
}

int Dinic(int st,int ed)
{
    int sum=0;
    while(bfs(st,ed))sum+=dfs(st,ed,inf);
    return sum;
}


int main()
{
    int i,j,k,u,v;
    scanf("%d%d",&m,&n);
    for(i=1;i<=m;i++)g[0][i]=1;
    for(i=m+1;i<=n;i++)g[i][n+1]=1;
    n++;
    scanf("%d%d",&u,&v);
    while(u!=-1&&v!=-1)
    {
        g[u][v]=1;
        scanf("%d%d",&u,&v);
    }
    k=Dinic(0,n);
    if(k==0)puts("No solution!");
    else
    {
        printf("%d\n",k);
        for(i=1;i<=m;i++)
        {
            for(j=m+1;j<=n;j++)
            if(g[j][i]!=0)printf("%d %d\n",i,j);
        }
    }
}

好艰难 我觉得我只会 对着模板抄

P3381最小费用最大流

求最大流量下的最小费用

#include<bits/stdc++.h>
#define debug printf("!");
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;


struct P{
    int to,flow,dis,next;
}p[50500<<1];
int head[50500<<1],pnum;

void add(int from,int to,int flow,int dis)
{
    p[++pnum].next=head[from];
    p[pnum].to=to;
    p[pnum].flow=flow;
    p[pnum].dis=dis;
    head[from]=pnum;
}


int dis[5050],vis[5050],pre[5050],last[5050],flow[5050];


bool spaf_bfs(int s,int t)
{
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(flow,inf,sizeof(flow));
    queue<int> que;
    que.push(s);dis[s]=0;pre[t]=-1;vis[s]=1;
    while(!que.empty())
    {
        int u=que.front();que.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=p[i].next)
        {
            if(p[i].flow>0&&dis[p[i].to]>dis[u]+p[i].dis)
            {
                dis[p[i].to]=dis[u]+p[i].dis;
                pre[p[i].to]=u;
                last[p[i].to]=i;
                flow[p[i].to]=min(flow[u],p[i].flow);
                if(!vis[p[i].to])
                {
                    vis[p[i].to]=1;
                    que.push(p[i].to);
                }
            }
        }
    }
    return pre[t]!=-1;
}

void solve(int s,int t,int &w,int &c)
{
    w=0;c=0;
    while(spaf_bfs(s,t))
    {
        int u=t;
        w+=flow[t];
        c+=flow[t]*dis[t];
        while(u!=s)
        {
            p[last[u]].flow-=flow[t];
            p[last[u]^1].flow+=flow[t];
            u=pre[u];
        }
    }
}



int main()
{
    memset(head,-1,sizeof(head));pnum=-1;
    int n,m,s,t,i,u,v,w,f;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(i=1;i<=m;i++)
    {
        scanf("%d%d%d%d",&u,&v,&w,&f);
        add(u,v,w,f);
        add(v,u,0,-f);
    }
    solve(s,t,u,v);
    printf("%d %d\n",u,v);
}

Gasoline

最大流+二分

借着别人的博客的二分 总算补完了这一题。

(用E_K算法会超时,用Dinic不会)

#include<bits/stdc++.h>
#define debug printf("!");
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;

struct P{
    int next,to,flow;
}p[22200<<1];
int head[22200<<1],pnum;
struct PP{
    int u,v,t;
    PP(){}
    PP(int uu,int vv,int tt){u=uu;v=vv;t=tt;}
}pp[20200];


void add(int from,int to,int flow)
{
    p[++pnum].next=head[from];
    p[pnum].to=to;
    p[pnum].flow=flow;
    head[from]=pnum;
}

int x,y,c,n,allsum,a[2020],b[2020];

int pre[2020],dep[2020];
bool vis[2020];


bool bfs(int st,int ed)
{
    memset(dep,-1,sizeof(dep));
    int u;
    queue<int>que;
    que.push(st);dep[st]=0;
    while(!que.empty())
    {
        u=que.front();que.pop();
        for(int i=head[u];i!=-1;i=p[i].next)
        {
            if(dep[p[i].to]==-1&&p[i].flow)
            {
                dep[p[i].to]=dep[u]+1;
                if(p[i].to==ed)return 1;
                que.push(p[i].to);
            }
        }
    }
    return dep[ed]!=-1;
}

int dfs(int st,int ed,int lim)
{
    if(!lim||st==ed)return lim;
    int w=0,d;
    for(int i=head[st];i!=-1;i=p[i].next)
    {
        if(dep[p[i].to]==dep[st]+1&&(d=dfs(p[i].to,ed,min(p[i].flow,lim))))
        {
            p[i].flow-=d;
            p[i^1].flow+=d;
            w+=d;
            lim-=d;
            if(!lim)break;
        }
    }
    return w;
}
int Dinic(int st,int ed)
{
    int sum=0;
    while(bfs(st,ed))sum+=dfs(st,ed,inf);
    return sum;
}
/*
int bfs(int st,int ed)
{
    memset(vis,0,sizeof(vis));
    int u,w=inf;
    queue<int>que;
    que.push(st);pre[st]=pre[ed]=-1;vis[st]=1;
    while(!que.empty())
    {
        u=que.front();que.pop();
        if(u==ed)break;
        for(int i=head[u];i!=-1;i=p[i].next)
        {
            if(vis[p[i].to]==0&&p[i].flow>0)
            {
                vis[p[i].to]=1;
                pre[p[i].to]=i;
                w=min(w,p[i].flow);
                que.push(p[i].to);
            }
        }
    }
    if(pre[ed]==-1)return 0;
    return w;
}

int E_K(int st,int ed)
{
    int w,sum=0;
    while(w=bfs(st,ed))
    {
        for(int i=pre[ed];i!=-1;i=pre[p[i^1].to])
        {
            p[i].flow-=w;
            p[i^1].flow+=w;
        }
        sum+=w;
    }
    return sum;
}*/

bool check(int mid)
{
    int i;
    memset(head,-1,sizeof(head));pnum=-1;
    for(i=1;i<=y;i++)
    {
        add(0,i,a[i]);
        add(i,0,0);
    }
    for(i=1;i<=x;i++)
    {
        add(y+i,n,b[i]);
        add(n,y+i,0);
    }
    for(i=1;i<=c;i++)
    {
        if(pp[i].t<=mid)
        {
            add(pp[i].u,pp[i].v+y,inf);
            add(pp[i].v+y,pp[i].u,0);
        }
    }
    int maxflow=Dinic(0,n);
    if(maxflow==allsum)return 1;
    return 0;
}

int main()
{
    allsum=0;
    int i,j,k,w;
    int u,v,t,l,r=0,mid,ans;
    scanf("%d%d%d",&x,&y,&c);
    n=x+y+1;
    for(i=1;i<=x;i++)
    {
        scanf("%d",&b[i]);
        allsum+=b[i];
    }
    for(i=1;i<=y;i++)scanf("%d",&a[i]);
    for(i=1;i<=c;i++)
    {
        scanf("%d%d%d",&v,&u,&t);
        pp[i]=PP(u,v,t);
        r=max(r,t);
    }
    l=0;ans=-1;r++;
    while(l<r)
    {
        mid=(l+r)>>1;
        if(check(mid))
        {
            ans=mid;
            r=mid;
        }
        else l=mid+1;
    }
    printf("%d\n",ans);
}

01-22 03:50