absi2011's Blog & Daily Life.

全新的开始       我要省选翻盘       I wanna AK in 高考\化学       自此,生无可恋
[破碎的状态] [-11] USACO 1.3 Wormholes
[破碎的状态] [-9] Hdu 2087

[破碎的状态] [-9] 546E

absi2011 posted @ Jul 13, 2016 03:18:21 PM in 刷题记录 with tags CF 网络流 小高考 , 525 阅读

网络流模版题

曾经在去年救过我省选的题,感谢周植

题意:有n个城市,第i个城市里一开始有ai个人

后来,有些人往某个相邻的城市走(只走一次),之后,第i个城市有bi个人

求是否有可能,如果可能,输出方案数,也就是说第i个城市有几个人往第j个城市走(i=j则表示没走的人)

这真的是网络流..不是最小割..

第i个城市向第j个连边,然后流一遍..求最大流..

代码:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<string>
#include<time.h>
#include<math.h>
#include<memory>
#include<vector>
#include<bitset>
#include<fstream>
#include<stdio.h>
#include<utility>
#include<sstream>
#include<string.h>
#include<iostream>
#include<stdlib.h>
#include<algorithm>
using namespace std;
int a[105],b[105];
int ans[105][105];
const int maxn=505;
const int inf=99999999;
struct edge
{
    int y;
    int weight;
    edge * next;
    edge * anti;
};
edge * li[1005];
edge * new_edge()
{
    static edge a[100005];
    static int top=0;
    return &a[top++];
}
edge * inserts(int x,int y,int z)
{
    edge * t=new_edge();
    t->y=y;
    t->weight=z;
    t->next=li[x];
    li[x]=t;
    return t;
}
void insert_edge(int x,int y,int z)
{
    edge * t1=inserts(x,y,z);
    edge * t2=inserts(y,x,0);
    t1->anti=t2;
    t2->anti=t1;
}
int dis[maxn];
bool bfs(int s,int t)
{
    static int que[maxn];
    int front=0,rail=1;
    memset(dis,-1,sizeof(dis));
    dis[s]=0;
    que[0]=s;
    for (;front<rail;front++)
    {
        int now=que[front];
        edge * x;
        for (x=li[now];x!=0;x=x->next)
        {
            if ((dis[x->y]==-1)&&(x->weight!=0))
            {
                dis[x->y]=dis[now]+1;
                if (x->y==t) return true;
                que[rail++]=x->y;
            }
        }
    }
    return false;
}
int max_flow(int s,int t)
{
    int tot=0;
    for (;bfs(s,t);)
    {
        static int pre[maxn];
        static edge * cur[maxn];
        static edge * path[maxn];
        memcpy(cur,li,sizeof(cur));
        int now=s;
        for (;dis[s]!=-1;)
        {
            if (now==t)
            {
                int temp;
                int mini=inf;
                for (temp=t;temp!=s;temp=pre[temp])
                {
                    mini=min(mini,path[temp]->weight);
                }
                tot+=mini;
                for (temp=t;temp!=s;temp=pre[temp])
                {
                    path[temp]->weight-=mini;
                    path[temp]->anti->weight+=mini;
                }
                now=s;
            }
            edge * x;
            for (x=li[now];x!=0;x=x->next)
            {
                if ((x->weight!=0)&&(dis[x->y]==dis[now]+1))
                {
                    pre[x->y]=now;
                    path[x->y]=x;
                    cur[now]=x;
                    now=x->y;
                    break;
                }
            }
            if (x==0)
            {
                dis[now]=-1;
                now=pre[now];
            }
        }
    }
    return tot;
}
int main()
{
    #ifdef absi2011
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
    #endif
    int n,m;
    scanf("%d%d",&n,&m);
    int i;
    int sum_a=0;
    for (i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
        sum_a+=a[i];
    }
    int sum_b=0;
    for (i=0;i<n;i++)
    {
        scanf("%d",&b[i]);
        sum_b+=b[i];
    }
    if (sum_a!=sum_b)
    {
        printf("NO\n");
        return 0;
    }
    int s=n*2,t=n*2+1;
    for (i=0;i<n;i++)
    {
        insert_edge(s,i,a[i]);
    }
    for (i=0;i<n;i++)
    {
        insert_edge(i+n,t,b[i]);
        insert_edge(i,i+n,inf);
    }
    for (i=0;i<m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        x--;
        y--;
        insert_edge(x,y+n,inf);
        insert_edge(y,x+n,inf);
    }
    int val=max_flow(s,t);
    if (val!=sum_a)
    {
        printf("NO\n");
    }
    else
    {
        printf("YES\n");
        for (i=0;i<n;i++)
        {
            edge * x;
            for (x=li[i+n];x!=0;x=x->next)
            {
                if (x->y==t) continue;
                ans[x->y][i]+=x->weight;
            }
        }
        for (i=0;i<n;i++)
        {
            int j;
            for (j=0;j<n;j++)
            {
                printf("%d ",ans[i][j]);
            }
            printf("\n");
        }
        return 0;
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter