zoukankan      html  css  js  c++  java
  • 简单网络流[不定期更新]

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

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

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

      

      

    #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!='
    ')
            {
                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的边.

  • 相关阅读:
    学习笔记:松弛
    学习笔记:可持久化线段树
    poj 3784 Running Median
    学习笔记:树状数组
    poj 2823 Sliding Window 题解
    学习笔记:状态压缩DP
    学习笔记:单调队列
    C++ 竞赛常用头文件
    mongodb lock 出毛病时解决方法
    ag使用需要注意的问题
  • 原文地址:https://www.cnblogs.com/qywyt/p/10553846.html
Copyright © 2011-2022 走看看