zoukankan      html  css  js  c++  java
  • POJ 1459&&3436

      两道比较基础的网络流题目,重点就是建图。

      1458:题意就是给你一些东西它们的数据,其中一些是发电站,还有一些是用户的家里,其中还有一些是中转站。让你求最大的输送电量。

      就是一道很基础的最大流题目,建超级源和汇,分别向发电站连边,从用户那连进边。

      具体的读入只需要写一下读优即可去括号。、

      CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=105,INF=1e9;
    struct edge
    {
        int to,next,c;
    }e[N*N*10];
    int head[N],dep[N],q[N*10],n,np,nc,m,k,i,x,y,z,s,t;
    inline void read(int &x)
    {
        x=0; char ch=getchar();
        while (ch<'0'||ch>'9') ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    }
    inline void write(int x)
    {
        if (x/10) write(x/10);
        putchar(x%10+'0');
    }
    inline void add(int x,int y,int z)
    {
        e[++k].to=y; e[k].c=z; e[k].next=head[x]; head[x]=k;
    }
    inline int min(int a,int b)
    {
        return a<b?a:b;
    }
    inline int BFS()
    {
        memset(dep,0,sizeof(dep));
        int H=0,T=1;
        q[1]=s; dep[s]=1;
        while (H<T)
        {
            int now=q[++H];
            for (int i=head[now];i!=-1;i=e[i].next)
            if (!dep[e[i].to]&&e[i].c>0)
            {
                dep[e[i].to]=dep[now]+1;
                q[++T]=e[i].to;
            }
        }
        return dep[t];
    }
    inline int DFS(int now,int dist)
    {
        if (now==t) return dist;
        int res=0;
        for (int i=head[now];i!=-1&&dist;i=e[i].next)
        if (dep[e[i].to]==dep[now]+1&&e[i].c>0)
        {
            int dis=DFS(e[i].to,min(dist,e[i].c));
            dist-=dis; res+=dis;
            e[i].c-=dis; e[i^1].c+=dis;
        }
        if (!res) dep[now]=0;
        return res;
    }
    inline int Dinic()
    {
        int sum=0;
        while (BFS()) sum+=DFS(s,INF);
        return sum;
    }
    int main()
    {
        while (scanf("%d",&n)!=EOF)
        {
            memset(e,-1,sizeof(head));
            memset(head,-1,sizeof(head));
            read(np); read(nc); read(m); s=0; t=n+2; k=-1;
            for (i=1;i<=m;++i)
            {
                read(x); read(y); read(z);
                add(x+1,y+1,z); add(y+1,x+1,0);
            }
            for (i=1;i<=np;++i)
            {
                read(x); read(z);
                add(s,x+1,z); add(x+1,s,0);
            }
            for (i=1;i<=nc;++i)
            {
                read(x); read(z);
                add(x+1,t,z); add(t,s+1,0);
            }
            write(Dinic()); putchar('
    ');
        }
        return 0;
    }

      3456:题意比较难理解,而且还要输出方案。

      大概是有n个工厂加工一种产品,其中每个产品都有p个部分。

      其中1表示必须要这个部件,0表示必须不要,2表示可有可无。

      然后给出所有工厂的单位时间内最多加工量和对输入输出的要求,让你求单位时间内最多加工多少个完整的产品(即所有部件都是1,刚开始所有的都是0)。

      思路:拆点,对于所有的工厂拆成两个点分别连入度和出度。对于所有工厂间若可以连成流水线就连一条INF的边。

      同时,由超级源向所有没有1的工厂连INF的边,所有没有1,2的工厂向超级汇连边。

      注意必须用scanf(雾),用read超时(滑稽)

      写了两个版本

      EK CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=55<<1,P=15<<1,INF=1e9;
    int f[N],pre[N],q[N],c[N][N],a[N][P],n,p,x,s,t,m;
    inline void write(int x)
    {
        if (x/10) write(x/10);
        putchar(x%10+'0');
    }
    inline int min(int a,int b)
    {
        return a<b?a:b;
    }
    inline int BFS(void)
    {
        memset(pre,-1,sizeof(pre));
        memset(f,0,sizeof(f));
        f[s]=INF; q[1]=s;
        int head=0,tail=1;
        while (head<tail)
        {
            int now=q[++head];
            for (register int i=s;i<=t;++i)
            if (pre[i]==-1&&c[now][i])
            {
                pre[i]=now;
                f[i]=min(f[now],c[now][i]);
                q[++tail]=i;
            }
        }
        return f[t];
    }
    inline int max_flow(void)
    {
        int sum=0,inc;
        while (inc=BFS())
        {
            int now=t;
            while (now!=s)
            {
                c[pre[now]][now]-=inc;
                c[now][pre[now]]+=inc;
                now=pre[now];
            }
            sum+=inc;
        }
        return sum;
    }
    int main()
    {
        register int i,j,k;
        while (scanf("%d%d",&p,&n)!=EOF)
        {
            memset(c,0,sizeof(c));
            s=0; t=2*n+1; m=0;
            for (i=1;i<=n;++i)
            {
                scanf("%d",&x);
                c[i][i+n]=x; 
                bool flag_0=1,flag_1=1;
                for (j=1;j<=p;++j)
                {
                    scanf("%d",&a[i][j]);
                    if (a[i][j]==1) flag_0=0;
                }
                for (j=1;j<=p;++j)
                {
                    scanf("%d",&a[i][j+p]);
                    if (a[i][j+p]!=1) flag_1=0;
                }
                if (flag_0) c[s][i]=INF;
                if (flag_1) c[i+n][t]=INF;
            }
            for (i=1;i<=n;++i)
            for (j=1;j<=n;++j)
            {
                bool flag=1;
                for (k=1;k<=p;++k)
                if (a[i][k+p]+a[j][k]==1) { flag=0; break; }
                if (flag) c[i+n][j]=INF;
            }
            write(max_flow()); putchar(' ');
            for (i=n+1;i<=2*n;++i)
            for (j=1;j<=n;++j)
            if (c[j][i]&&i-n!=j) ++m;
            write(m); putchar('
    ');
            for (i=n+1;i<=2*n;++i)
            for (j=1;j<=n;++j)
            if (c[j][i]&&i-n!=j) write(i-n),putchar(' '),write(j),putchar(' '),write(c[j][i]),putchar('
    ');
        }
        return 0;
    }

      Dinic CODE

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int N=55<<1,P=15<<1,INF=1e9;
    struct data
    {
        int to,next,c;
    }e[N*N];
    int head[N],dep[N],q[N],a[N][P],n,p,x,s,t,m,tot;
    inline void write(int x)
    {
        if (x/10) write(x/10);
        putchar(x%10+'0');
    }
    inline void add(int x,int y,int z)
    {
        e[++tot].to=y; e[tot].c=z; e[tot].next=head[x]; head[x]=tot;
    }
    inline int min(int a,int b)
    {
        return a<b?a:b;
    }
    inline bool BFS(void)
    {
        memset(dep,0,sizeof(dep));
        q[1]=s; dep[s]=1;
        int H=0,T=1;
        while (H<T)
        {
            int now=q[++H];
            for (register int i=head[now];i!=-1;i=e[i].next)
            if (!dep[e[i].to]&&e[i].c)
            {
                dep[e[i].to]=dep[now]+1;
                q[++T]=e[i].to;
            }
        }
        return dep[t];
    }
    inline int DFS(int now,int dist)
    {
        if (now==t) return dist;
        int res=0;
        for (register int i=head[now];i!=-1&&dist;i=e[i].next)
        if (dep[e[i].to]==dep[now]+1&&e[i].c)
        {
            int dis=DFS(e[i].to,min(e[i].c,dist));
            dist-=dis; res+=dis;
            e[i].c-=dis; e[i^1].c+=dis;
        }
        if (!res) dep[now]=0;
        return res;
    }
    inline int Dinic(void)
    {
        int sum=0;
        while (BFS()) sum+=DFS(s,INF);
        return sum;
    }
    inline int abs(int x)
    {
        return x>0?x:-x;
    }
    int main()
    {
        register int i,j,k;
        while (scanf("%d%d",&p,&n)!=EOF)
        {
            memset(e,-1,sizeof(e));
            memset(head,-1,sizeof(head));
            s=0; t=2*n+1; m=0; tot=-1;
            for (i=1;i<=n;++i)
            {
                scanf("%d",&x);
                add(i,i+n,x); add(i+n,i,0);
                bool flag_0=1,flag_1=1;
                for (j=1;j<=p;++j)
                {
                    scanf("%d",&a[i][j]);
                    if (a[i][j]==1) flag_0=0;
                }
                for (j=1;j<=p;++j)
                {
                    scanf("%d",&a[i][j+p]);
                    if (a[i][j+p]!=1) flag_1=0;
                }
                if (flag_0) add(s,i,INF),add(i,s,0);
                if (flag_1) add(i+n,t,INF),add(t,i+n,0);
            }
            for (i=1;i<=n;++i)
            for (j=1;j<=n;++j)
            {
                bool flag=1;
                for (k=1;k<=p;++k)
                if (a[i][k+p]+a[j][k]==1) { flag=0; break; }
                if (flag) add(i+n,j,INF),add(j,i+n,0);
            }
            write(Dinic()); putchar(' ');
            for (i=1;i<=tot;i+=2)
            if (e[i].c&&abs(e[i].to-e[i-1].to)!=n&&e[i].to!=s&&e[i-1].to!=t) ++m;
            write(m); putchar('
    ');
            for (i=1;i<=tot;i+=2)
            if (e[i].c&&abs(e[i].to-e[i-1].to)!=n&&e[i].to!=s&&e[i-1].to!=t) write(e[i].to-n),putchar(' '),write(e[i-1].to),putchar(' '),write(e[i].c),putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    《统计学习方法》笔记十 隐马尔可夫模型
    《统计学习方法》笔记九 EM算法及其推广
    《统计学习方法》笔记八 提升方法
    《统计学习方法》笔记七(3) 支持向量机——非线性支持向量机
    拜拜~~~
    拓扑排序+DP CF721C Journey
    数学 CF1068B LCM
    扩展欧拉定理【洛谷P4139】 上帝与集合的正确用法
    浅谈扩展欧拉定理
    数论 CF230B T-primes
  • 原文地址:https://www.cnblogs.com/cjjsb/p/8671854.html
Copyright © 2011-2022 走看看