网络流24题+简单网络流[不更新了]

  干网络流!


 

  之前刷过一点校oj的网络流,现在忘得差不多了,开始在loj刷一下网络流24题。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=210,MAXM=5010;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline ll read(){
    ll This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
ll mod=998244353;
struct edge
{
    int y,next;
    ll v;
}e[MAXM*2];
int head[MAXN],v[MAXN],d[MAXN];
int tot=1;
int n,m,s,t;
queue<int>q;
void add(int x,int y,ll v)
{
    tot++;
    e[tot].y=y;
    e[tot].v=v;
    e[tot].next=head[x];
    head[x]=tot;
}
bool bfs()
{
    memset(d,0,sizeof(d));
    q.push(s);
    d[s]=1;
    while(q.size())
    {
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=e[i].next)
        {
            if(e[i].v&&d[e[i].y]==0)
            {
                d[e[i].y]=d[x]+1;
                q.push(e[i].y);
            }
        }
    }
    return d[t];
}
ll dfs(int x,ll flow)
{
    if(x==t)
        return flow;
    ll sum=0;
    for(int i=head[x];i;i=e[i].next)
    {
        if(e[i].v&&d[e[i].y]==d[x]+1)
        {
            ll res=dfs(e[i].y,min(flow,e[i].v));
            e[i].v-=res;
            e[i^1].v+=res;
            flow-=res;
            sum+=res;
        }
    }
    if(sum==0)
        d[x]=0; 
    return sum;
}
int tx,ty;
ll ans=0;
int main()
{
freopen("1.in","r",stdin);
    n=read();m=read();s=read();t=read();
    for(int i=1;i<=m;i++)
    {
        tx=read();ty=read();
        add(tx,ty,read());
        add(ty,tx,0);
    }
    while(bfs())
        ans+=dfs(s,1e18);
    cout<<ans;
}
https://www.luogu.com.cn/problem/P3376

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=110;
struct edge
{
    int y,next;
    ll v;
}e[MAXN*2+MAXN*MAXN];
int head[MAXN],v[MAXN],d[MAXN];
int tot=1;
int s,t;
queue<int>q;
void add(int x,int y,ll v)
{
    tot++;
    e[tot].y=y;
    e[tot].v=v;
    e[tot].next=head[x];
    head[x]=tot;
}
bool bfs()
{
    memset(d,0,sizeof(d));
    q.push(s);
    d[s]=1;
    while(q.size())
    {
        int x=q.front();
        q.pop();
        for(int i=head[x];i;i=e[i].next)
        {
            if(e[i].v&&d[e[i].y]==0)
            {
                d[e[i].y]=d[x]+1;
                q.push(e[i].y);
            }
        }
    }
    return d[t];
}
ll dfs(int x,ll flow)
{
    if(x==t)
        return flow;
    ll sum=0;
    for(int i=head[x];i;i=e[i].next)
    {
        if(e[i].v&&d[e[i].y]==d[x]+1)
        {
            ll res=dfs(e[i].y,min(flow,e[i].v));
            e[i].v-=res;
            e[i^1].v+=res;
            flow-=res;
            sum+=res;
        }
    }
    if(sum==0)
        d[x]=0; 
    return sum;
}
int n,m,a,b;
ll ans;
int main()
{
    //freopen("1.in","r",stdin);
    cin>>n>>m; 
    s=0;t=n+1;
    for(int i=1;i<=m;i++)
    {
        add(s,i,1);
        add(i,s,0);
    }
    for(int i=m+1;i<=n;i++)
    {
        add(i,t,1);
        add(t,i,0);
    }
    while(cin>>a>>b)
    {
        add(a,b,1);
        add(b,a,0);
    }
    while(bfs())
        ans+=dfs(s,1e18);
    cout<<ans;
}
搭配飞行员

 

 

 

 

  以下是原文


 

  嗯,本文应该叫:网络流刷题柱.

  差不多了,都是造福群众嘛~

  题目来源:传送门+传送门

  

  

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
const int oo=1000000;
int n,m,a[300][300],sum=0,forward;
bool vis[300],check=1;
void dfs(int k,int l=oo)
{
    vis[k]=1;
    if(k==n)
    {
        check=1;
        sum+=l;
        forward=l;
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if((a[k][i]>0)&&(!vis[i]))
        {
            dfs(i,min(a[k][i],l));
            if (check)
            {
                a[k][i]-=forward;
                a[i][k]+=forward;
                return;
            }
        }
    }
}
int main()
{
    //freopen("123.in","r",stdin);
    m=read();n=read();
    for(int i=1;i<=m;i++)
    {
        int x=read(),y=read();
        a[x][y]+=read();
    }
    while(check)
    {
        check=0;
        memset(vis,0,sizeof(vis));
        dfs(1);
    }
    cout<<sum;
    return 0;
 }
p1318

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
const int oo=1000000;
int n,m,d,a[310][310],sum=0,forward;
bool vis[310],check=1;
void dfs(int k,int l=oo)
{
    vis[k]=1;
    if(k==n+d+1)
    {
        check=1;
        sum+=l;
        forward=l;
        return;
    }
    for(int i=0;i<=n+d+1;i++)
    {
        if((a[k][i]>0)&&(!vis[i]))
        {
            dfs(i,min(a[k][i],l));
            if (check)
            {
                a[k][i]-=forward;
                a[i][k]+=forward;
                return;
            }
        }
    }
}
int k;
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    n=read();k=read();d=read();
    for(int i=1;i<=d;i++)//0 
    {
        a[i+n][d+n+1]+=read();
    }
    for(int i=1;i<=n;i++)//0源点 1-n牛  d+n 菜
    {
        int f=read();
        //cout<<f<<endl;
        a[0][i]=k;
        for(;f;f--)
            a[i][read()+n]=1;
    }
    while(check)
    {
        check=0;
        memset(vis,0,sizeof(vis));
        dfs(0);
        //cout<<sum<<endl;    
    }/*
    for(int i=0;i<=d+n+1;i++)
    {
        for(int f=0;f<=d+n+1;f++)
        {
            if(a[i][f])
                cout<<endl<<i<<' '<<f<<' '<<a[i][f];
        }
    }*/
    cout<<sum;
    return 0;
 }
p1319

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
int n,m,inf=123456789;
//int a[3010][3010],check,v[3010],forward,ans;
int check,v[3010],forward,ans;
struct edge
{
    int y,v,next;
}e[50010];
int tot,head[2010];

/*

void dfs(int x,int l=inf)
{
    //cout<<x<<endl;
    v[x]=1;
    if(x==n)
    {
        check=1;
        forward=l;
        ans+=l;
        return ;
    }
    for(int i=1;i<=2*n;i++)
    {
        if(a[x][i]>0&&!v[i])
        {
            dfs(i,min(l,a[x][i]));
            if(check)
            {
                a[x][i]-=forward;
                a[i][x]+=forward;
                return ;
            }
        }
    }
}*/
void add(int x,int y,int v=inf)
{
    tot++;
    e[tot]=(edge){y,v,head[x]};
    head[x]=tot;
}
void dfs(int x,int l=inf)
{
    v[x]=1;
    if(x==n){
        check=1;
        forward=l;
        ans+=l;
        return ;
    }
    for(int i=head[x];i;i=e[i].next)
    {
        if(e[i].v>0&&!v[e[i].y])
        {
            dfs(e[i].y,min(l,e[i].v));
            if(check)
            {
                e[i].v-=forward;
                e[i^1].v+=forward;
                return ;
            }
        }
    }
}
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    n=read();m=read();tot=1;
    for(register int i=2;i<n;i++)
    {
        add(i,i+n,1);
        add(i+n,i,1);
        /*a[i][i+n]=1;
        a[i+n][i]=1;*/
    }
    for(;m;m--)
    {
        int tx=read();
        int ty=read();
        if(tx>ty)
            swap(tx,ty);
        if(tx==1)
        {
            //a[1][ty]=inf;
            add(1,ty);
            add(ty,1,0);
        }
        else if(ty==n)
        {
            //a[tx+n][n]=inf;
            //a[n][tx]=0;
            add(tx+n,n);
            add(n,tx+n,0);
        }
        else
        {
            /*a[tx+n][ty]=inf;
            a[ty+n][tx]=inf;*/
            add(tx+n,ty);
            add(ty,tx+n,0);
            add(ty+n,tx);
            add(tx,ty+n,0);
        }
    }
    /*for(int i=1;i<=2*n;i++)
        for(int f=1;f<=2*n;f++)
            if(a[i][f])
                cout<<i<<' '<<f<<' '<<a[i][f]<<endl;*/
    /*for(int i=2;i<=tot;i++)
    {
        if(e[i].v)
            cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl;
    }*/
    check=1;
    while(check)
    {
        check=0;
        memset(v,0,sizeof(v));
        dfs(1);
    }
    cout<<(ans==0?ans:ans-1);/*//cout<<' '<<clock();*/
}
p1320

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}

inline void write(int x){
    if(x==0){
        putchar('0');
        return;
    }
    if(x<0){
        putchar('-');
        x=-x;
    }
    int num=0;char ch[16];
    while(x) ch[++num]=x%10+'0',x/=10;
    while(num) putchar(ch[num--]);
}
int inf=987654321;
int n,m,s[1010][25],ans=100000,/*a[1025][1025],*/head[1025],check,forward,v[1025],sum[25],G,tot;
struct edge
{
    int y,v,next;
}e[200010];
void add(int x,int y,int v)
{
    tot++;
    e[tot]=(edge){y,v,head[x]};
    head[x]=tot;
}
void dfs(int x,int l=inf)
{
    if(x==n+m+1)
    {
        check=1;
        forward=l;
        G+=l;
        return ;
    }
    v[x]=1;
    /*for(register int i=1;i<=n+m+1;i++)
    {*/
    for(register int i=head[x];i;i=e[i].next)
    {
        if(e[i].v/*a[x][i]*/&&!v[e[i].y])
        {
            dfs(e[i].y,min(l,e[i].v));//a[x][i]));
            if(check)
            {
                /*a[x][i]-=forward;
                a[i][x]+=forward;*/
                e[i].v-=forward;
                e[i^1].v+=forward;
                return ;
            }
        }
    }
}
int main()
{
    /*freopen("123.in","r",stdin);
    freopen("123.out","w",stdout);*/
    n=read();m=read();
    for(register int i=1;i<=n;i++)
        for(int f=1;f<=m;f++)
            s[i][f]=read();
    for(register int i=1;i<=m;i++)
        sum[i]=read();
    for(register int l=1;l<=m;l++)
    {
        for(register int r=l;l+ans-1>r&&r<=m;r++)
        {
            //memset(a,0,sizeof(a));
            memset(head,0,sizeof(head));
            tot=1;
            for(register int i=1;i<=n;i++)
            {
                //a[0][i]=1;
                add(0,i,1);
                add(i,0,0);
                for(register int f=l;f<=r;f++)
                    //a[i][s[i][f]+n]=1;
                    add(i,s[i][f]+n,1),add(s[i][f]+n,i,1);
            }
            for(register int i=1;i<=m;i++)
                //a[i+n][n+m+1]=sum[i];
                add(i+n,n+m+1,sum[i]),add(n+m+1,i+n,0);
            G=0;
            check=1;
            while(check)
            {
                check=0;
                memset(v,0,sizeof(v));
                dfs(0);
            }
            if(G==n)
            {
                ans=min(ans,r-l+1);
                break;
            }
        }
    }
    cout<<ans;
    //cout<<' '<<clock();
}
p1325

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}

inline void write(int x){
    if(x==0){
        putchar('0');
        return;
    }
    if(x<0){
        putchar('-');
        x=-x;
    }
    int num=0;char ch[16];
    while(x) ch[++num]=x%10+'0',x/=10;
    while(num) putchar(ch[num--]);
}
const int N=5010,M=200010;
int head[N],d[N],incf[N],pre[N],v[N];
int n,m,k,tot,s,t,maxflow,ans;
struct edge
{
    int y,l,v,next;
}e[M];
void add(int x,int y,int z,int c)
{
    e[++tot].y=y;e[tot].l=z;e[tot].v=c;
    e[tot].next=head[x];head[x]=tot;
    e[++tot].y=x;e[tot].v=-c;
    e[tot].next=head[y];head[y]=tot;
}
int num(int i,int j,int k)
{
    return (i-1)*m+j+k*n*m;
}
bool spfa()
{
    queue<int>q;
    memset(d,0xcf,sizeof(d));
    memset(v,0,sizeof(v));
    q.push(s);
    d[s]=0;
    v[s]=1;
    incf[s]=1<<30;
    while(q.size())
    {
        int x=q.front();
        v[x]=0;
        q.pop(); 
        for(int i=head[x];i;i=e[i].next)
        {
            if(!e[i].l)continue;
            int y=e[i].y;
            if(d[y]<d[x]+e[i].v)
            {
                d[y]=d[x]+e[i].v;
                incf[y]=min(incf[x],e[i].l);
                pre[y]=i;
                if(!v[y])v[y]=1,q.push(y);
            }
        }
    }
    if(d[t]==0xcfcfcfcf)return 0;
    return 1;
}
void update()
{
    int x=t;
    while(x!=s)
    {
        int i=pre[x];
        e[i].l-=incf[t];
        e[i^1].l+=incf[t];
        x=e[i^1].y;
    }
    maxflow+=incf[t];
    ans+=d[t]*incf[t];
}
int main()
{
    //freopen("123.in","r",stdin);
    n=read();m=read();
    k=2;
    tot=s=1,t=2*n*m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            int c=read();
            add(num(i,j,0),num(i,j,1),1,c);
            add(num(i,j,0),num(i,j,1),k-1,0);
            if(j<m)add(num(i,j,1),num(i,j+1,0),k,0);
            if(i<n)add(num(i,j,1),num(i+1,j,0),k,0);
        }
    }
    while(spfa())
        update();
    write(ans);
    return 0;
}
p1670

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
int inf=123456789,forward,check,ans,v[110];
int n,m,head[110],tot,can[1010],sum[1010];
//int e[10][10];
struct edge
{
    int y,v,next;
}e[100010];
void add(int x,int y,int v)
{
    tot++;
    e[tot]=(edge){y,v,head[x]};
    head[x]=tot;
    //e[x][y]=v;
}
void dfs(int x,int l=10*inf)
{
    v[x]=1;
    if(x==n+1)
    {
        check=1;
        ans+=l;
        forward=l;
        return ;
    }
    for(register int i=head[x];i;i=e[i].next)
    {
        if(e[i].v>0&&!v[e[i].y])
        {
            dfs(e[i].y,min(l,e[i].v));
            if(check)
            {
                e[i].v-=forward;
                e[i^1].v+=forward;
                return ;
            }
        }
    }    /*
    for(register int i=0;i<=n+1;i++)
    {
        if(a[x][i]>0&&!v[i])
        {
            dfs(*/
}
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    tot=1;
    m=read();
    n=read();
    for(register int i=1;i<=m;i++)
        sum[i]=read();
    for(register int i=1;i<=n;i++)
    {
        for(register int A=read();A;A--)
        {
            int a=read();
            if(can[a])
            {
                add(can[a],i,inf);
                add(i,can[a],0);
            }
            else 
            {
                add(0,i,sum[a]);
                add(i,0,0);
            }
            can[a]=i;
        }
        add(i,n+1,read());
        add(n+1,i,0);
    }
    /*for(register int i=2;i<=tot;i++)
    {
        if(e[i].v)
            cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl;
    }*/
    check=1;
    while(check)
    {
        check=0;
        memset(v,0,sizeof(v));
        dfs(0);
    }
    cout<<ans;
    /*for(register int i=2;i<=tot;i++)
    {
        if(e[i].v)
            cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl;
    }*/
}
p1609

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
const int oo=1000000;
int n,m,d,F,a[410][410],sum=0,forward;
bool vis[410],check=1;
void dfs(int k,int l=oo)
{
    vis[k]=1;
    if(k==2*n+d+F+1)
    {
        check=1;
        sum+=l;
        forward=l;
        return;
    }
    for(int i=0;i<=2*n+d+F+1;i++)
    {
        if((a[k][i]>0)&&(!vis[i]))
        {
            dfs(i,min(a[k][i],l));
            if (check)
            {
                a[k][i]-=forward;
                a[i][k]+=forward;
                return;
            }
        }
    }
}
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    n=read();F=read();d=read();
    for(int i=1;i<=n;i++)
    {
        int f=read(),j=read();
        for(;f;f--)
        {
            a[read()+2*n][i]=1;
        }
        for(;j;j--)
        {
            a[i+n][read()+2*n+F]=1;
        }
        a[i][i+n]=1;
    }
    for(int i=1;i<=F;i++)
    {
        a[0][i+2*n]=1;
    }
    for(int i=1;i<=d;i++)
    {
        a[i+2*n+F][d+2*n+F+1]=1;
    }
    while(check)
    {
        check=0;
        memset(vis,0,sizeof(vis));
        dfs(0);
    }
    /*for(int i=0;i<=2*n+d+F+1;i++)
    {
        for(int f=0;f<=2*n+d+F+1;f++)
        {
            if(a[i][f])
            {
                cout<<i<<' '<<f<<' '<<a[i][f]<<endl;
            }
        }
    }*/
    cout<<sum;
}
p1324

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
int inf=123456789;
int n,m,c1,c2,a[210][210],b[210][210],v[210],check,forward,G,G0;
void dfs(int x,int l=inf)
{
    if(x==c2)
    {
        forward=l;
        check=1;
        G+=forward;
        return ;
    }
    v[x]=1;
    for(int i=1;i<=2*n;i++)
    {
        if(a[x][i]>0&&!v[i])
        {
            dfs(i,min(l,a[x][i]));
            if(check)
            {
                a[x][i]-=forward;
                a[i][x]+=forward;
                return ;
            }
        }
    }
}
int main()
{
    n=read();m=read();c1=read();c2=read();
    if(c1>c2)
        swap(c1,c2);
    for(int i=1;i<=n;i++)
        if(i!=c1&&i!=c2)
            a[i][i+n]=1,a[i+n][i]=1;
    for(;m;m--)
    {
        int tx=read();int ty=read();
        if(ty==c1)
            swap(tx,ty);
        if(tx==c2)
            swap(tx,ty);
        if(tx==c1)
            a[c1][ty]=inf;
        else if(ty==c2)
            a[tx+n][c2]=inf;
        else
            a[tx+n][ty]=1,a[ty+n][tx]=1;
    }//建图
    memcpy(b,a,sizeof(a));//存边
    check=1;
    while(check)
    {
        check=0;
        memset(v,0,sizeof(v));
        dfs(c1);
    }
    cout<<G<<endl;//跑出最小割
    int sum=G0=G;
    for(int now=1;sum;now++)//枚举当前要删那个点
    {
        if(now==c1||now==c2)
            continue;
        G=0;
        memcpy(a,b,sizeof(a));
        for(int i=1;i<=2*n;i++)
            a[now][i]=a[i][now]=a[now+n][i]=a[i][now+n]=0;
        check=1;
        while(check)
        {
            check=0;
            memset(v,0,sizeof(v));
            dfs(c1);
        }//跑删掉这个点后的最小割
        if(G<G0)//如果小于的话就更新G0,删边
        {
            G0=G;
            cout<<now<<' ';
            sum--;
            for(int i=1;i<=2*n;i++)
                b[now][i]=b[i][now]=b[now+n][i]=b[i][now+n]=0;
        }
        
    }
    //cout<<clock();
}
p1342

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}

inline void write(int x){
    if(x==0){
        putchar('0');
        return;
    }
    if(x<0){
        putchar('-');
        x=-x;
    }
    int num=0;char ch[16];
    while(x) ch[++num]=x%10+'0',x/=10;
    while(num) putchar(ch[num--]);
}
struct edge
{
    int x,y,v,i;
}e[1010];
bool v_(edge a,edge b)
{
    return a.v>b.v;
}
int n,m,inf=987654321;
int check,forward,a[40][40],b[40][40],G,G0,v[40];
void dfs(int x,int l=inf)
{
    if(x==n)
    {
        check=1;
        forward=l;
        G+=l;
        return ;
    }
    v[x]=1;
    for(int i=1;i<=n;i++)
    {
        if(a[x][i]&&!v[i])
        {
            dfs(i,min(l,a[x][i]));
            if(check)
            {
                a[x][i]-=forward;
                a[i][x]+=forward;
                return ;
            }
        }
    }
}
int sum;
int main()
{
    //freopen("123.in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        int tx=read(),ty=read(),tv=read();
        e[i]=(edge){tx,ty,tv,i};
        a[tx][ty]+=tv;
        sum+=tv;
    }
    sort(e+1,e+1+m,v_);
    memcpy(b,a,sizeof(a));
    check=1;
    while(check)
    {
        check=0;
        memset(v,0,sizeof(v));
        dfs(1);
    }
    G0=G;
    write(G0);
    putchar(32);
    priority_queue<int>q;
    for(int i=1;i<=m;i++)
    {
        G=0;
        memcpy(a,b,sizeof(a));
        a[e[i].x][e[i].y]-=e[i].v;
        check=1;
        while(check)
        {
            check=0;
            memset(v,0,sizeof(v));
            dfs(1);
        }
        if(G==G0-e[i].v)
        {
            q.push(-e[i].i);
            G0=G;
            b[e[i].x][e[i].y]-=e[i].v;
        }
    }
    write(q.size());
    putchar(10);
    while(q.size())
    {
        write(-q.top());
        putchar(10);
        q.pop();
    }
    return 0;
}
p1341

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
int inf=987654321;
int head[1010],tot,d[1010];
int n,m,maxflow;
queue<int>q;
struct edge
{
    int x,y,v,next;
}e[1000010];
void add(int x,int y,int v)
{
    tot++;
    e[tot].x=x;
    e[tot].y=y;
    e[tot].v=v;
    e[tot].next=head[x];
    head[x]=tot;
}
bool bfs()
{
    memset(d,0,sizeof(d));
    while(q.size()) 
        q.pop();
    q.push(1);d[1]=1;
    while(q.size())
    {
        int x=q.front();q.pop();
        for(int i=head[x];i;i=e[i].next)
        {
            if(e[i].v&&!d[e[i].y])
            {
                q.push(e[i].y);
                d[e[i].y]=d[x]+1;
                if(e[i].y==n)return 1;
            }
        }
    }
    return 0;
}

int dinic(int x,int flow)
{
    if(x==n)
        return flow;
    int rest=flow,k;
    for(int i=head[x];i&&rest;i=e[i].next)
    {
        if(e[i].v&&d[e[i].y]==d[x]+1)
        {
            k=dinic(e[i].y,min(rest,e[i].v));
            if(!k)d[e[i].y]=0;
            e[i].v-=k;
            e[i^1].v+=k;
            rest-=k;
        }
    }
    return flow-rest;
}
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    m=read();n=read();
    //1=read();n=read();
    tot=1;
    for(int i=1;i<=m;i++)
    {
        int tx=read(),ty=read(),tv=read();
        add(tx,ty,tv);
        add(ty,tx,0);
    }
    int flow=0;
    while(bfs())
    {
        while(flow=dinic(1,inf))
            maxflow+=flow;
    }
    cout<<maxflow;
}
p1671

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
/*char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}*/
char temp;
int n,m,a[60],tot,head[110],inf=987654321,forward,check,G,v[110],sum;
struct edge
{
    int x,y,v,next;
}e[100000];
void add(int x,int y,int v=inf)
{
    tot++;
    e[tot].x=x;
    e[tot].y=y;
    e[tot].v=v;
    e[tot].next=head[x];
    head[x]=tot;
}
void dfs(int x,int l=inf)
{
    v[x]=1;
    if(x==m+n+1)
    {
        forward=l;
        check=1;
        G+=forward;
        return ;
    }
    for(int i=head[x];i;i=e[i].next)
    {
        if(e[i].v>0&&!v[e[i].y])
        {
            dfs(e[i].y,min(l,e[i].v));
            if(check)
            {
                e[i].v-=forward;
                e[i^1].v+=forward;
                return ;
            }
        }
    }
}
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    cin>>m>>n;
    tot=1;
    for(int i=1;i<=m;i++)
    {
        int x;
        scanf("%d",&x);
        add(0,i,x);
        add(i,0,0);
        sum+=x;
        scanf("%c",&temp);
        while(temp!='\n')
        {
            int x;
            scanf("%d",&x);
            add(i,m+x);
            add(m+x,i,0);
            scanf("%c",&temp);
        }
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]),add(m+i,m+n+1,a[i]),add(m+n+1,m+i,0);
    check=1;
    while(check)
    {
        check=0;
        memset(v,0,sizeof(v));
        dfs(0);
    }
    cout<<sum-G;
}
p1343

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
const int N=510,M=3010;
int m,n,k,d[N],b[N][N],inf=987654321,o[N],v[N],head[N],tot,ans[N];
struct edge
{
    int x,y,v,next;
}e[M*3];
queue<int>q;
void add(int x,int y,int v)
{
    tot++;
    e[tot]=(edge){x,y,v,head[x]};
    head[x]=tot;
}
bool bfs()
{
    memset(d,0,sizeof(d));
    while(q.size())
        q.pop();
    q.push(0);d[0]=1;
    while(q.size())
    {
        int x=q.front();q.pop();
        for(int i=head[x];i;i=e[i].next)
        {
            if(e[i].v&&!d[e[i].y])
            {
                q.push(e[i].y);
                d[e[i].y]=d[x]+1;
                if(e[i].y==n+1)
                    return 1;
            }
        }
    }
    return 0;
}
int dinic(int x,int flow)
{
    if(x==n+1)
        return flow;
    int rest=flow,k;
    for(int i=head[x];i&&rest;i=e[i].next)
    {
        if(e[i].v&&d[e[i].y]==d[x]+1)
        {
            k=dinic(e[i].y,min(rest,e[i].v));
            if(!k)
                d[e[i].y]=0;
            e[i].v-=k;
            e[i^1].v+=k;
            rest-=k;
        }
    }
    return flow-rest;
}
void get(int now,int move)
{
    v[now]=1;
    ans[now]|=(1<<move);
    for(int i=head[now];i;i=e[i].next)
        if(e[i].v&&!v[e[i].y])
            get(e[i].y,move);
}
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        int x=read();int y=read();
        b[x][y]=b[y][x]=1;
    }
    k=read();
    for(int i=1;i<=k;i++)
    {
        o[i]=read();
        ans[o[i]]=read();
    }
    for(int i=0;i<=31;i++)
    {
        memset(head,0,sizeof(head));
        tot=1;
        for(int now=1;now<=k;now++)
        {
            if((1<<i)&ans[o[now]])
            {
                add(0,o[now],inf);
                add(o[now],0,0);
            }
            else 
            {
                add(o[now],n+1,inf);
                add(n+1,o[now],0);
            }
        }
        for(int f=1;f<=n;f++)
        {
            for(int j=1;j<=n;j++)
            {
                if(b[f][j])
                {
                    add(f,j,1);
                    add(j,f,1);
                }
            }
        }
        /*if((1<<i)==8)
            for(int j=1;j<=tot;j++)
            {
                if(e[j].v)
                    cout<<e[j].x<<' '<<e[j].y<<' '<<e[j].v<<endl;
            }*/

        
        int flow;
        while(bfs())
        {
            flow=1;
            while(flow)
            {
                flow=dinic(0,inf);
            }
        }
        memset(v,0,sizeof(v));
        get(0,i);
    }
    for(int i=1;i<=n;i++)
        cout<<ans[i]<<endl;
}
p1349

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
const double eps=1e-4;
double min(double a,double b)
{
    return a>b?b:a;
}
double inf=987654321;
int n,m,head[1200],tot,d[1200],v[1200];
struct edge{
    int x,y,next;
    double v;
}e[10000];
struct node{
    int a,b;
}o[10000];
void add(int x,int y,double v=inf){
    tot++;
    e[tot]=(edge){x,y,head[x],v};
    head[x]=tot;
}
bool bfs(){
    memset(d,0,sizeof(d));
    queue<int>q;
    q.push(0);d[0]=1;
    while(q.size())    
    {
        int x=q.front();q.pop();
        for(int i=head[x];i;i=e[i].next)
            if(e[i].v>=eps&&!d[e[i].y])
            {
                q.push(e[i].y);
                d[e[i].y]=d[x]+1;
                if(e[i].y==n+m+1)
                    return 1;
            }
    }
    return 0;
}
double dinic(int x,double flow){
    if(x==n+m+1)
        return flow;
    double rest=flow,k;
    for(int i=head[x];i&&rest>=eps;i=e[i].next)
        if(e[i].v>=eps&&d[e[i].y]==d[x]+1)
        {
            k=dinic(e[i].y,min(rest,e[i].v));
            if(k<eps)
                d[e[i].y]=0;
            e[i].v-=k;
            e[i^1].v+=k;
            rest-=k;
            if(rest<eps)
                return flow-rest;
        }
    return flow-rest;
}
int main()
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","w",stdout);
    n=read();m=read();
    for(int i=1;i<=m;i++)
        o[i]=(node){read(),read()};
    double l=0,r=m,mid;
    while(l+1e-4<r)
    {
        mid=(l+r)/2;
        tot=1;
        memset(head,0,sizeof(head));
        for(int i=1;i<=m;i++)
        {
            add(0,i+n,1);
            add(i+n,0,0);
            add(i+n,o[i].a);
            add(o[i].a,i+n,0);
            add(i+n,o[i].b);
            add(o[i].b,i+n,0);
        }
        for(int i=1;i<=n;i++)
            add(i,n+m+1,mid),add(n+m+1,i,0);
        /*for(int i=1;i<=tot;i++)
        {
            if(e[i].v)
                cout<<e[i].x<<' '<<e[i].y<<' '<<e[i].v<<endl;
        }*/

        double G=0,flow=0;
        while(bfs())
        {
            while((flow=dinic(0,inf))>eps)
                G+=flow;
        }
        if(m-G>0)
            l=mid;
        else
            r=mid;
    }
    cout<<setiosflags(ios::fixed)<<setprecision(3);
    cout<<l;
}
p1639初步算法

 

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<complex>
#include<queue>
#include<deque>
#include<set>
#include<bitset>
#define eps 1e-12
using namespace std ;
char buf[1<<15],*fs,*ft;
inline char getc(){
  return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:* fs++;
}
inline int read(){
    int This=0,F=1; char ch=getc();
    while(ch<'0'||ch>'9'){
        if(ch=='-') F=-1;
        ch=getc();
    }
    while(ch>='0'&&ch<='9'){
        This=(This<<1)+(This<<3)+ch-'0';
        ch=getc();
    }
    return This*F;
}
struct edge
{
    int x,y;
    double v;
    int next ;
}e[10000],p[1200];
int head[120],tot,inf=987654321;
int d[120],n,m,con[120];
int vis[120],num;
queue<int>q;
void add(int x,int y,double v)
{
    tot++;
    e[tot]=(edge){x,y,v,head[x]};
    head[x]=tot;
}
int bfs() 
{
    memset(d,0,sizeof(d));
    d[0]=1;
    q.push(0);
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(register int i=head[x];i;i=e[i].next) 
        {
            if(!d[e[i].y]&&e[i].v>=eps)
            {
                d[e[i].y]=d[x]+1 ;
                q.push(e[i].y);
            }
        }
    }
    if(d[n+1]>0) return 1 ;
    return 0 ;
}
double dinic(int x,double flow)
{
    if(x==n+1)
        return flow;
    double rest=flow,k;
    for(register int i=head[x];i&&rest>eps;i=e[i].next)
    {
        if(e[i].v>eps&&d[e[i].y]==d[x]+1)
        {
            k=dinic(e[i].y,min(rest,e[i].v));
            if(k<eps)
                d[e[i].y]=0;
            e[i].v-=k;
            e[i^1].v+=k;
            rest-=k;
        }
    }
    return flow-rest;
}
double ask(double k)
{
    memset(head,0,sizeof(head));
    tot=1;
    double temp,max_flow=0;
    for(register int i=1;i<=m;i++)
    {
        add(p[i].x,p[i].y,1.0);
        add(p[i].y,p[i].x,1.0);
    }
    for(register int i=1;i<=n;i++)
    {
        add(0,i,m);
        add(i,0,0);
        add(i,n+1,m+2*k-con[i]);
        add(n+1,i,0);
    }
    while(bfs())
        while((temp=dinic(0,m))>=eps)
            max_flow+=temp ;
    return ((double)m*n-max_flow)/2;
}
int main() 
{
    //freopen("123.in","r",stdin);
    //freopen("123.out","v",stdout);
    n=read();m=read();
    for(register int i=1;i<=m;i++) 
    {
        p[i].x=read();p[i].y=read();
        con[p[i].x]++;
        con[p[i].y]++;
    }
    double l,r,mid,temp;
    l=0;r=m;
    while(r-l>=1e-4)
    {
        mid=(l+r)/2;
        temp=ask(mid);
        if(temp>=eps)
            l=mid;
        else
            r=mid;
    }
    cout<<setiosflags(ios::fixed)<<setprecision(3);
    cout<<l;
}
p1639优化算法

 

 

 

网络流最难的是建图.我就把建图说一下好了.


   p1318

  裸的最大流吧.对于每个边都把邻接矩阵+=v.

  跑最大流.


  p1319

  和p1324有点像啊...

  令0为源点,1-n为牛,n+1到n+d为菜,n+d+1为汇点.

  每个菜向汇点连一条权值为菜的数量的边,从源点向每个牛连一条权值为这个牛会做的菜的数量的边(权值也可以为inf),每个牛向它所有能做的菜连一条权值为1的边.

  跑最大流.


 

 

   p1320.

  无向图,求至少割几个点使得1到n不连通.输出答案减一.

  把点拆成i和i+n,连双向边,流量都是1.

  对于图中的边,如果是(1,y)这样的形式就连1到y.如果是(x,n)这样的形式就连x+n,n.否则对于(x,y),连(x+n,y)和(y+n,x).这些都是单向边且流量为inf.我们还需要建一个反向边以供增广.

  然后从1往外跑最大流.输出最大流>0?最大流-1:最大流.


   p1325

  要求"郁闷指数跨度"最小.

  可以每次枚举郁闷指数的左右区间,令源点到牛们连一条流量为1的边,牛向当前枚举到的区间里的牛棚连一条流量为1的边,再从牛棚向汇点连一条长为牛棚容量限制的边,

  虽然可以二分,但是写了个小优化就过去了,最慢的也不过265ms.


  p1670

  水了个n^4dp,以后再填坑.

  

  

  2333

 

  康神tql.

  当只能走一遍的时候,我们可以跑一遍最短路完事~.

  否则就是一个同时有权值和限制的最优化问题.也就是最大费用最大流.

  继续拆点,令入点为1-n^2,n^2+1-2n^2为出点.每个格子从入点到出点连两条边:第一条容量为1,费用为到达这个格子的"好心程度",第二条容量为1,费用为0.每个格子的出点向右边和下边的格子的入点连一条容量为2,费用为0的边.

  然后开始跑最大费用最大流. 


  p1609

  令0为源点,1-n为顾客,n+1为汇点.

  先把猪圈里猪的数量存起来.

  维护每个猪圈最后一次是被哪个顾客打开的.对于每个顾客能打开的猪圈,如果之前有顾客打开过就从上一个顾客连一条流量为inf的边,否则从源点向顾客连一条流量为该猪圈里猪的数量的边.最后向汇点连一条流量为需求的边.更新"最后一次是被哪个顾客打开的".


  p1324

  把点拆成1-n和n+1到2*n,令0为源点,2*n+1-2*n+F为食品,2*n+F+1到2*n+F+d为饮料,2*n+F+d+1为汇点.先连边i到i+n约束牛,汇点连食品,饮料们连源点. 对于牛i,食品连i,i+n连饮料.以上边权都为1.


  p1342

  p1320的加强版.拆点后跑最大流.记录当前最大流为G0.为了输出字典序最小字典序的方案,从小到大枚举所有的点,假装删掉这个点,看最大流G是否小于G0.如果小于说明是可以删掉它,更新G0,真的删掉这个点.否则把那些边还回去...


  p1341

  第一问是正经的最小割.设最大流为G0.

   第二问类比上一题(果然应该先写上一题).为了最小化,我们按边权枚举所有的边,尝试着删去后看最大流G是否刚好减少了v.如果刚好减少了v就放入一个堆里,把边删掉,更新G0.否则继续.


   p1671=p1318

  终于还是学了dinic...


   p1343

  最大权闭合子图.

  一个有n个点的点权和m条边的网络流图,求闭合子图中点权和最大的那个点权和.

  

  

  我们原图保持不变,但是边权设为inf表示不可割.从S向所有点权为正的边连一条边权为点权的边,从所有点权为负的点向T连一条边权为点权的边.然后跑最小割即最大流.最大点权和即为正点权和-最大流.

    

  为什么可以这样做呢?可以从最小割的角度来理解.

  考虑最小割的实际意义:表示我不要这个边了,那么在原图中就表示为不要这个点了.或实验,或仪器.如果把实验的那个边删了表示放弃了这个实验的收益,如果把仪器那边删了表示不需要这个仪器,那么那边的实验就做不了了.

  


 

  p1349

  

 


 

  

 

 

 

 

  

 


 

  p1672

  找到了一个贪心的算法,非常的厉害.

  传送门

  


 

  p1673

  看上去是很裸的最小费用最大流.

  拿到题当然要先分析题意.然后,先不管费用,建一个符合题意的最大流模型.

  发现要满足每天有ni个毛巾,于是就想到了拆点建图.

  

 

  根据题意这样建图好像没什么问题.

  但是一会要跑最小费用最大流了,但是i+n到i+a的那些边是用不到的,因为

  

 

  源点向1-i连一条容量为need[i],费用为f的边表示这天直接买了多少的新毛巾,花费为f.然后连一条连向汇点,费用为为0的边.

 
 
 
posted @ 2019-03-18 18:07  zzuqy  阅读(249)  评论(0编辑  收藏  举报