zoukankan      html  css  js  c++  java
  • toj 1421

    题意:假如存在矩阵A,A[i][0] + A[i][1] + ...... + A[i][n - 1] == SR[i],A[0][j] + A[1][j] + ...... + A[n - 1][j] == SC[j].(0 <= A[i][j] <= 100),输出YES并输出任意一个满足条件的矩阵A,若不存在则输出NO

    分析:SR[0] + SR[1] + ...... + SR[n - 1] == SC[0] + SC[1] + ...... + SC[n - 1],建图的重点是把银行和公司之间的边的容量都设为100,作为流的上限.

    当图的最大流等于SR的和则找到了满足条件的矩阵.

    另外,输出矩阵时,由于建图方法的特殊性,要用栈来倒序输出.

    #include <cstdio>
    #include <cstring>
    const int MAXN=205;//点数的最大值
    const int MAXM=25005;//边数的最大值
    const int INF=0x3fffffff;
    
    struct Node
    {
        int from,to,next;
        int cap;
    }edge[MAXM];
    
    int tol;
    int head[MAXN];
    int dep[MAXN];
    int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y
    
    int n;//n是总的点的个数,包括源点和汇点
    
    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++;
    }
    void BFS(int start,int end)
    {
        memset(dep,-1,sizeof(dep));
        memset(gap,0,sizeof(gap));
        gap[0]=1;
        int que[MAXN];
        int front,rear;
        front=rear=0;
        dep[end]=0;
        que[rear++]=end;
        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(dep[v]!=-1)continue;
                que[rear++]=v;
                if(rear==MAXN)rear=0;
                dep[v]=dep[u]+1;
                ++gap[dep[v]];
            }
        }
    }
    int SAP(int start,int end)
    {
        int res=0;
        BFS(start,end);
        int cur[MAXN];
        int S[MAXN];
        int top=0;
        memcpy(cur,head,sizeof(head));
        int u=start;
        int i;
        while(dep[start]<n)
        {
            if(u==end)
            {
                int temp=INF;
                int inser;
                for(i=0;i<top;i++)
                   if(temp>edge[S[i]].cap)
                   {
                       temp=edge[S[i]].cap;
                       inser=i;
                   }
                for(i=0;i<top;i++)
                {
                    edge[S[i]].cap-=temp;
                    edge[S[i]^1].cap+=temp;
                }
                res+=temp;
                top=inser;
                u=edge[S[top]].from;
            }
            if(u!=end&&gap[dep[u]-1]==0)//出现断层,无增广路
              break;
            for(i=cur[u];i!=-1;i=edge[i].next)
               if(edge[i].cap!=0&&dep[u]==dep[edge[i].to]+1)
                 break;
            if(i!=-1)
            {
                cur[u]=i;
                S[top++]=i;
                u=edge[i].to;
            }
            else
            {
                int min=n;
                for(i=head[u];i!=-1;i=edge[i].next)
                {
                    if(edge[i].cap==0)continue;
                    if(min>dep[edge[i].to])
                    {
                        min=dep[edge[i].to];
                        cur[u]=i;
                    }
                }
                --gap[dep[u]];
                dep[u]=min+1;
                ++gap[dep[u]];
                if(u!=start)u=edge[S[--top]].from;
            }
        }
        return res;
    }
    int main()
    {
        int sr,sc,sum;
        while(~scanf("%d",&n))
        {
            int N = n;
            n = 2 * n + 2;
            init();
            int s = n - 2,t = n - 1;
            sum = 0;
            for(int i = 0;i < N;i++)
            {
                scanf("%d",&sr);
                sum += sr;
                addedge(s,i,sr);
            }
            for(int i = 0;i < N;i++)
            {
                scanf("%d",&sc);
                addedge(N + i,t,sc);
            }
            for(int i = 0;i < N;i++)
            {
                for(int j = 0;j < N;j++)
                {
                    addedge(i,N + j,100);
                }
            }
            if(SAP(s,t) == sum)
            {
                printf("YES
    ");
                int stk[105],sn = 0;
                for(int i = 0;i < N;i++)
                {
                    for(int j = head[i];edge[j].next != -1;j = edge[j].next)
                    {
                        stk[sn++] = 100 - edge[j].cap;
                    }
                    printf("%d",stk[--sn]);
                    while(sn > 0)
                    {
                        printf(" %d",stk[--sn]);
                    }
                    printf("
    ");
                }
            }
            else
                printf("NO
    ");
        }
        return 0;
    }
  • 相关阅读:
    修复 Visual Studio Error “No exports were found that match the constraint”
    RabbitMQ Config
    Entity Framework Extended Library
    Navisworks API 简单二次开发 (自定义工具条)
    NavisWorks Api 简单使用与Gantt
    SQL SERVER 竖表变成横表
    SQL SERVER 多数据导入
    Devexpress GridControl.Export
    mongo DB for C#
    Devexress XPO xpPageSelector 使用
  • 原文地址:https://www.cnblogs.com/ZShogg/p/3229474.html
Copyright © 2011-2022 走看看