zoukankan      html  css  js  c++  java
  • POJ1459:Power Network(dinic)

    题目链接:http://poj.org/problem?id=1459

    题意:有n个结点,np个发电站,nc个消费者,m个电力运输线。接下去是m条边的信息(u,v)cost,cost表示边(u,v)的最大流量;a个发电站的信息(u)cost,cost表示发电站u能提供的最大流量;b个用户的信息(v)cost,cost表示每个用户v能接受的最大流量。
    思路:在图中添加1个源点S和汇点T,将S和每个发电站相连,边的权值是发电站能提供的最大流量;将每个用户和T相连,边的权值是每个用户能接受的最大流量。从而转化成了一般的最大网络流问题,然后求解。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #include <math.h>
    #define N 1100
    #define inf 0x3f3f3f3f
    typedef int ll;
    using namespace std;
    ll n,np,nc,m,tt,dis[N],head[N];
    struct node
    {
        ll x,y,w,next;
    } eg[N*N];
    void init()
    {
        tt=0;
        memset(head,-1,sizeof(head));
    }
    void add(int xx,int yy,int ww)
    {
        eg[tt].x=xx;
        eg[tt].y=yy;
        eg[tt].w=ww;
        eg[tt].next=head[xx];
        head[xx]=tt++;
        eg[tt].x=yy;
        eg[tt].y=xx;
        eg[tt].w=0;
        eg[tt].next=head[yy];
        head[yy]=tt++;
    }
    bool bfs(int s,int e)
    {
        memset(dis,-1,sizeof(dis));
        dis[s]=0;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int fa=q.front();
            q.pop();
            for(int i=head[fa]; i!=-1; i=eg[i].next)
            {
                int v=eg[i].y;
                if(dis[v]==-1&&eg[i].w)
                {
                    dis[v]=dis[fa]+1;
                    q.push(v);
                }
            }
        }
        if(dis[e]>0)
            return true;
        return false;
    }
    int dinic(int s,int maxt)
    {
        if(s==n+1) return maxt;
        int a,sum=maxt;
        for(int i=head[s]; i!=-1; i=eg[i].next)
        {
            int v=eg[i].y;
            if(dis[v]==dis[s]+1&&eg[i].w>0)
            {
                a=dinic(v,min(sum,eg[i].w));
                eg[i].w-=a;
                eg[i+1].w+=a;
                sum-=a;
            }
        }
        return maxt-sum;
    }
    int main()
    {
        ll xx,yy,ww;
        while(scanf("%d%d%d%d",&n,&np,&nc,&m)!=EOF)
        {
            init();
            while(m--)
            {
                while(getchar()!='(') ;
                scanf("%d,%d)%d",&xx,&yy,&ww);
                add(xx+1,yy+1,ww);
            }
            for(int i=0; i<np; i++)
            {
                while(getchar()!='(') ;
                scanf("%d)%d",&xx,&yy);
                add(0,xx+1,yy);
            }
            for(int i=0; i<nc; i++)
            {
                while(getchar()!='(') ;
                scanf("%d)%d",&xx,&yy);
                add(xx+1,n+1,yy);
            }
            ll ans=0;
            while(bfs(0,n+1))
            {
                ans+=dinic(0,inf);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    html学习总结
    16--二叉树的镜像
    17-- 从上到下打印二叉树,按层打印。
    14--反转链表
    14--合并两个排序的链表
    15-- 输入两个二叉树A和B,判断B树是否包含于A树。
    13--输入一个整数数组,实现一个函数来调整数组中数字的顺序
    13--输出链表中倒数第k个节点,
    12--打印1到最大的N为数字。
    10--输入一个十进制的整数,转化为二进制,输出有多少个1
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/4252850.html
Copyright © 2011-2022 走看看