網絡流代碼小全

  嗯,我又來造福羣衆了.

#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<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<deque>
#include<set>
using namespace std; 
int ans[60][60][60][60],o[60][60];
int n,m;
int i,f;
int xi,yi,xf,yf;
inline int maxx(int a,int b,int c,int d)
{
    return max(max(a,b),max(c,d));
}
int main()
{    
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
//freopen("123.in","r",stdin);
    cin>>n>>m;
    for(i=1;i<=n;i++)
        for(f=1;f<=m;f++)
            cin>>o[i][f];
    for(xi=2;xi<=n;xi++)
        for(yi=1;yi<m;yi++)
            for(xf=1;xf<xi;xf++)
                for(yf=2;yf<=m;yf++)
                    ans[xi][yi][xf][yf]=maxx(ans[xi-1][yi][xf-1][yf],ans[xi-1][yi][xf][yf-1],ans[xi][yi-1][xf-1][yf],ans[xi][yi-1][xf][yf-1])+o[xi][yi]+o[xf][yf];
    cout<<ans[n][m-1][n-1][m];
}
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<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define oo 0x7fffffff
using namespace std;
int head,tail,level[110],q[110],s,t,sum=0,rev[10010],len,lin[110];
int m,n,Id[10010],cnt,ans;
struct node{
    int y,v,ne;
}edge[10010];

struct node1{
    int v,id;
}e[10010];

inline bool mycmp(node1 a,node1 b)
{return a.v>b.v||a.v==b.v&&a.id<b.id;}

inline bool mycmp1(int a,int b)
{return a<b;}
void addedge(int x,int y,int v)
{
    edge[++len].y=y;edge[len].v=v;edge[len].ne=lin[x];lin[x]=len;rev[len]=len+1;
    edge[++len].y=x;edge[len].v=0;edge[len].ne=lin[y];lin[y]=len;rev[len]=len-1;
}

int read(){
    int x=0,y=1;char ch=getchar();
    while (!isdigit(ch)){if (ch=='-')y=-1;ch=getchar();}
    while (isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    return x*y;
}

bool make_level(){
    head=0,tail=1;q[1]=s;memset(level,-1,sizeof(level));level[s]=0;
    while (head++<tail){
        int tn=q[head];
        for (int i=lin[tn],y;i;i=edge[i].ne)
            if (edge[i].v&&level[y=edge[i].y]==-1){
                level[y]=level[tn]+1;
                q[++tail]=y;
            }
    }
    return level[t]!=-1;
}

int max_flow(int k,int flow){
    if (k==t)    return flow;
    int maxflow=0,d;
    for (int i=lin[k];i&&maxflow<flow;i=edge[i].ne)
        if (edge[i].v&&level[edge[i].y]==level[k]+1)
            if (d=max_flow(edge[i].y,min(flow-maxflow,edge[i].v))){
                edge[i].v-=d;edge[rev[i]].v+=d;maxflow+=d;
            }
    if (!maxflow)level[k]=-1;
    return maxflow;
}

void dinic(){
    int d;
    while (make_level())    while (d=max_flow(s,oo))    sum+=d;
}

void init(){
    n=read();m=read();
    s=1,t=n;
    int x,y,v;
    for (int i=1;i<=m;i++){
        x=read();y=read();v=read();
        addedge(x,y,v);
    }
}

int main(){
    init();
    dinic();
    printf("%d ",sum);
    ans=sum;
    for (int j=1;j<=len;j+=2){edge[j].v+=edge[rev[j]].v;edge[rev[j]].v=0;}
    for (int i=1;i<=m;i++){e[i].v=edge[i*2-1].v;e[i].id=i;}
    sort(e+1,e+1+m,mycmp);
    for (int i=1;i<=m&&ans;i++){
        int id=e[i].id,v=e[i].v;
        sum=0;
        edge[id*2-1].v=0;
        dinic();
        for (int j=1;j<=len;j+=2){edge[j].v+=edge[rev[j]].v;edge[rev[j]].v=0;}
        if (ans-sum==v){
            ans=sum;
            Id[++cnt]=id;
        }
        else edge[id*2-1].v=v;
    }
    printf("%d\n",cnt);
    sort(Id+1,Id+1+cnt);
    for (int i=1;i<=cnt;i++)    printf("%d\n",Id[i]);
    return 0;
}
p1341

 

  網絡流最難的是建圖.我就把建圖說一下好了.


   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:最大流.


  p1670

  水了個n^4dp,以後再填坑.


  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

  第一問是正經的最小割.

 

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章