网络流入门

poj1459

http://poj.org/problem?id=1459

电站由组成consumer,dispatcher,power station,问最大传输电流

题意故意弄得非常复杂,其实就是多源多汇点,那么只要设置一个s往所有的源连,把所有的汇连到一个t再dinic就行了。

值得注意的两点:1.init必须在所有的开头调用 2.这题的(1,2)20这种读入比较奇葩,只要先读入buf,然后sscanf("(%d,%d)%d")就可以了

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<string>
#include<cctype>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<ctime>
using namespace std;
#define For(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,k,n) for(int i=n;i>=k;i--)
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define NEG(a) memset(a,-1,sizeof(a));
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define print(b,a) cout<<b<<"="<<a<<endl;
#define printbin(b,a){int tmp=a;string s;do{s+=tmp%2+'0';tmp/=2;}while(tmp);reverse(s.begin(),s.end());cout<<"bin "<<b<<"="<<s<<endl;}
#define printarr(i,a,f,b) {For(i,f,b) printf("%d ",a[i]); printf("\n");}

#define MAXN 20000
#define MAXM 200000
struct Node
{
    int from,to,next;
    int cap;
}edge[MAXM];
int tol;

int dep[MAXN];//dep为点的层次
int head[MAXN];

void init()
{
    tol=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)//第一条变下标必须为偶数
{
    edge[tol].from=u;
    edge[tol].to=v;
    edge[tol].cap=w;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].from=v;
    edge[tol].to=u;
    edge[tol].cap=0;
    edge[tol].next=head[v];
    head[v]=tol++;
    //printf("u=%d v=%d w=%d\n",u,v,w);
}

int BFS(int start,int end)
{
    int que[MAXN];
    int front,rear;
    front=rear=0;
    memset(dep,-1,sizeof(dep));
    que[rear++]=start;
    dep[start]=0;
    while(front!=rear)
    {
        int u=que[front++];
        if(front==MAXN)front=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].cap>0&&dep[v]==-1)
            {
                dep[v]=dep[u]+1;
                que[rear++]=v;
                if(rear>=MAXN)rear=0;
                if(v==end)return 1;
            }
        }
    }
    return 0;
}
int dinic(int start,int end)
{
    int res=0;
    int top;
    int stack[MAXN];//stack为栈,存储当前增广路
    int cur[MAXN];//存储当前点的后继
    while(BFS(start,end))
    {
        //printf("res=%d\n",res);
        memcpy(cur,head,sizeof(head));
        int u=start;
        top=0;
        while(1)
        {
            if(u==end)
            {
                int min=INF;
                int loc;
                for(int i=0;i<top;i++)
                  if(min>edge[stack[i]].cap)
                  {
                      min=edge[stack[i]].cap;
                      loc=i;
                  }
                for(int i=0;i<top;i++)
                {
                    edge[stack[i]].cap-=min;
                    edge[stack[i]^1].cap+=min;
                }
                res+=min;
                top=loc;
                u=edge[stack[top]].from;
            }
            for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)
              if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])
                 break;
            if(cur[u]!=-1)
            {
                stack[top++]=cur[u];
                u=edge[cur[u]].to;
            }
            else
            {
                if(top==0)break;
                dep[u]=-1;
                u=edge[stack[--top]].from;
            }
        }
    }
    return res;
}
char buf[MAXN];
int main()
{
    //freopen("in.txt","r",stdin);
    int n,np,nc,m;
    int u,v,cap;
    while(scanf("%d%d%d%d",&n,&np,&nc,&m)==4)
    {
        init();
        For(i,0,m-1)
        {
            scanf("%s",buf);
            sscanf(buf,"(%d,%d)%d",&u,&v,&cap);
            u++;v++;
            addedge(u,v,cap);
        }
        For(i,0,np-1)
        {
            scanf("%s",buf);
            sscanf(buf,"(%d)%d",&u,&cap);
            u++;
            addedge(0,u,cap);
        }
        For(i,0,nc-1)
        {
            scanf("%s",buf);
            sscanf(buf,"(%d)%d",&u,&cap);
            u++;
            addedge(u,n+1,cap);
        }
        printf("%d\n",dinic(0,n+1));
    }
    return 0;
}
View Code

 

poj1698

http://poj.org/problem?id=1698

alice要拍n部电影,每部电影要至少拍di天,必须要wi天内拍完,给出每个电影能在一个礼拜那些天拍。问能否拍完

s往电影连di,电影往所有能拍的天连1,所有的天往t连1,最大流

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<string>
#include<cctype>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<ctime>
using namespace std;
#define For(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,k,n) for(int i=n;i>=k;i--)
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define NEG(a) memset(a,-1,sizeof(a));
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define print(b,a) cout<<b<<"="<<a<<endl;
#define printbin(b,a){int tmp=a;string s;do{s+=tmp%2+'0';tmp/=2;}while(tmp);reverse(s.begin(),s.end());cout<<"bin "<<b<<"="<<s<<endl;}
#define printarr(i,a,f,b) {For(i,f,b) printf("%d ",a[i]); printf("\n");}

#define MAXN 20000
#define MAXM 200000
struct Node
{
    int from,to,next;
    int cap;
}edge[MAXM];
int tol;

int dep[MAXN];//dep为点的层次
int head[MAXN];
int a[MAXN][10];

void init()
{
    tol=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)//第一条变下标必须为偶数
{
    edge[tol].from=u;
    edge[tol].to=v;
    edge[tol].cap=w;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].from=v;
    edge[tol].to=u;
    edge[tol].cap=0;
    edge[tol].next=head[v];
    head[v]=tol++;
    //printf("u=%d v=%d w=%d\n",u,v,w);
}

int BFS(int start,int end)
{
    int que[MAXN];
    int front,rear;
    front=rear=0;
    memset(dep,-1,sizeof(dep));
    que[rear++]=start;
    dep[start]=0;
    while(front!=rear)
    {
        int u=que[front++];
        if(front==MAXN)front=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].cap>0&&dep[v]==-1)
            {
                dep[v]=dep[u]+1;
                que[rear++]=v;
                if(rear>=MAXN)rear=0;
                if(v==end)return 1;
            }
        }
    }
    return 0;
}
int dinic(int start,int end)
{
    int res=0;
    int top;
    int stack[MAXN];
    int cur[MAXN];
    while(BFS(start,end))
    {
        memcpy(cur,head,sizeof(head));
        int u=start;
        top=0;
        while(1)
        {
            if(u==end)
            {
                int min=INF;
                int loc;
                for(int i=0;i<top;i++)
                  if(min>edge[stack[i]].cap)
                  {
                      min=edge[stack[i]].cap;
                      loc=i;
                  }
                for(int i=0;i<top;i++)
                {
                    edge[stack[i]].cap-=min;
                    edge[stack[i]^1].cap+=min;
                }
                res+=min;
                top=loc;
                u=edge[stack[top]].from;
            }
            for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)
              if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])
                 break;
            if(cur[u]!=-1)
            {
                stack[top++]=cur[u];
                u=edge[cur[u]].to;
            }
            else
            {
                if(top==0)break;
                dep[u]=-1;
                u=edge[stack[--top]].from;
            }
        }
    }
    return res;
}
char buf[MAXN];
int main()
{
    //freopen("in.txt","r",stdin);
    int t;
    scanf("%d",&t);
    int flg=0;
    while(t--)
    {
        init();
        int n,sum=0;
        flg=0;
        scanf("%d",&n);
        For(i,1,n)
        {
            For(j,1,7) scanf("%d",&a[i][j]);
            int D,W;
            scanf("%d %d",&D,&W);
            addedge(0,i,D);
            sum+=D;
            if(flg<W) flg=W;
            For(k,0,W-1) 
                For(j,1,7)
                    if(a[i][j])
                        addedge(i,7*k+j+n,1);
        }
        int T=n+7*flg+1;
        For(i,0,flg-1) For(j,1,7) addedge(7*i+n+j,T,1);
        int ans=dinic(0,T);
        if(ans==sum) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
View Code

 

poj2112

http://poj.org/problem?id=2112 

有K台挤奶机(编号1~K),C头奶牛(编号K+1~K+C),给出各点之间距离。现在要让C头奶牛到挤奶机去挤奶,每台挤奶机只能处理M头奶牛,求使所走路程最远的奶牛的路程最短的方案。

非常简单,二分dinic

值得注意的只是二分的时候r设置大一点

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<cmath>
#include<string>
#include<cctype>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<ctime>
using namespace std;
#define For(i,k,n) for(int i=k;i<=n;i++)
#define ForD(i,k,n) for(int i=n;i>=k;i--)
#define Lson (x<<1)
#define Rson ((x<<1)+1)
#define MEM(a) memset(a,0,sizeof(a));
#define NEG(a) memset(a,-1,sizeof(a));
#define FILL(a) memset(a,0x3f,sizeof(a));
#define INF 0x3f3f3f3f
#define LLINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define print(b,a) cout<<b<<"="<<a<<endl;
#define printbin(b,a){int tmp=a;string s;do{s+=tmp%2+'0';tmp/=2;}while(tmp);reverse(s.begin(),s.end());cout<<"bin "<<b<<"="<<s<<endl;}
#define printarr(i,a,f,b) {For(i,f,b) printf("%d ",a[i]); printf("\n");}

#define MAXN 400000
struct Node
{
    int from,to,next;
    int cap;
}edge[MAXN];
int tol;

int dep[MAXN];//dep为点的层次
int head[MAXN];

void init()
{
    tol=0;
    memset(head,-1,sizeof(head));
}
void addedge(int u,int v,int w)//第一条变下标必须为偶数
{
    edge[tol].from=u;
    edge[tol].to=v;
    edge[tol].cap=w;
    edge[tol].next=head[u];
    head[u]=tol++;
    edge[tol].from=v;
    edge[tol].to=u;
    edge[tol].cap=0;
    edge[tol].next=head[v];
    head[v]=tol++;
    //printf("u=%d v=%d w=%d\n",u,v,w);
}

int BFS(int start,int end)
{
    int que[MAXN];
    int front,rear;
    front=rear=0;
    memset(dep,-1,sizeof(dep));
    que[rear++]=start;
    dep[start]=0;
    while(front!=rear)
    {
        int u=que[front++];
        if(front==MAXN)front=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].cap>0&&dep[v]==-1)
            {
                dep[v]=dep[u]+1;
                que[rear++]=v;
                if(rear>=MAXN)rear=0;
                if(v==end)return 1;
            }
        }
    }
    return 0;
}
int dinic(int start,int end)
{
    int res=0;
    int top;
    int stack[MAXN];
    int cur[MAXN];
    while(BFS(start,end))
    {
        memcpy(cur,head,sizeof(head));
        int u=start;
        top=0;
        while(1)
        {
            if(u==end)
            {
                int min=INF;
                int loc;
                for(int i=0;i<top;i++)
                  if(min>edge[stack[i]].cap)
                  {
                      min=edge[stack[i]].cap;
                      loc=i;
                  }
                for(int i=0;i<top;i++)
                {
                    edge[stack[i]].cap-=min;
                    edge[stack[i]^1].cap+=min;
                }
                res+=min;
                top=loc;
                u=edge[stack[top]].from;
            }
            for(int i=cur[u];i!=-1;cur[u]=i=edge[i].next)
              if(edge[i].cap!=0&&dep[u]+1==dep[edge[i].to])
                 break;
            if(cur[u]!=-1)
            {
                stack[top++]=cur[u];
                u=edge[cur[u]].to;
            }
            else
            {
                if(top==0)break;
                dep[u]=-1;
                u=edge[stack[--top]].from;
            }
        }
    }
    return res;
}
int d[250][250];
int K,C,M;
void floyd()
{
    For(k,1,K+C)
        For(i,1,K+C)
            For(j,1,K+C) 
                d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
   // For(i,1,K+C) For(j,1,K+C) printf("d[%d][%d]=%d\n",i,j,d[i][j] );
}
int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d%d%d",&K,&C,&M);
    For(i,1,K+C) 
        For(j,1,K+C) {
        scanf("%d",&d[i][j]);
        if(d[i][j]==0) d[i][j]=INF;
    }
    floyd();
    int l=1,r=9999999,ans=1;
    while(l<=r)
    {
        int m=(l+r)/2;
        //printf("m=%d\n",m);
        init();
        For(i,1,K) addedge(0,i,M);
        For(i,K+1,K+C) addedge(i,K+C+1,1);
        For(i,1,K) 
            For(j,K+1,K+C)
                if(m>=d[i][j]) addedge(i,j,1);
        int ret=dinic(0,K+C+1);
        //printf("ret=%d\n",ret);
        if(ret==C) 
        {
            r=m-1;
            ans=m;
        }
        else
        {
            l=m+1;
        }
    }
    printf("%d\n",ans);
    return 0;
}
View Code

 

poj2455

蜜汁无限tle,暂时搁置

 

posted @ 2016-07-30 10:08  aidgn  阅读(123)  评论(0编辑  收藏  举报