tjut 3061

#include <stdio.h>  
#include <string.h>  
#define VM 10000  
#define EM 120000  
#define inf 0x3f3f3f3f  
struct E  
{  
    int to,cap,nxt;  
}edge[EM];  
  
int head[VM],gap[VM],dist[VM],cur[VM],pre[VM];  
int ep;  
void addedge (int cu,int cv,int cw)  
{  
  
    edge[ep].to = cv;  
    edge[ep].cap = cw;  
    edge[ep].nxt = head[cu];  
    head[cu] = ep;  
    ep ++;  
    edge[ep].to = cu;  
    edge[ep].cap = 0;  
    edge[ep].nxt = head[cv];  
    head[cv] = ep;  
    ep ++;  
}  
int min (int a ,int b)  
{  
   return a > b ? b : a;  
}  
  
int sap (int src,int des,int n)  
{  
  
    memset (dist,0,sizeof(dist));  
    memset (gap,0,sizeof (dist));  
    memcpy (cur,head,sizeof(dist));  
    int res = 0;  
    int u = pre[src] = src;  
    int aug = inf;  
    gap[0] = n;  
    while (dist[src] < n)  
    {  
loop:  
        for (int &i = cur[u];i != -1;i = edge[i].nxt)  
        {  
            int v = edge[i].to;  
            if (edge[i].cap && dist[u] == dist[v] + 1)  
            {  
                aug = min (aug,edge[i].cap);  
                pre[v] = u;  
                u = v;  
                if (v == des)  
                {  
                    res += aug;  
                    for (u = pre[u];v != src;v = u,u = pre[u])  
                    {  
                        edge[cur[u]].cap -= aug;  
                        edge[cur[u]^1].cap += aug;  
                    }  
                    aug = inf; //  
                }  
                goto loop;  
            }  
        }  
        int mindist = n;  //  
        for (int i = head[u];i != -1;i = edge[i].nxt)  
        {  
            int v = edge[i].to;  
            if (edge[i].cap && mindist > dist[v])  
            {  
                cur[u] = i;  
                mindist = dist[v];  
            }  
        }  
        if ((--gap[dist[u]]) == 0)  
            break;  
        dist[u] = mindist + 1;  
        gap[dist[u]] ++;  
        u = pre[u];  
    }  
    return res;  
}  
int vis[VM];  
void dfs(int u,int v)  
{  
    if(u==v) return ;  
    vis[u]=1;  
    for(int i=head[u];i!=-1;i=edge[i].nxt)  
    if(edge[i].cap>0&&!vis[edge[i].to])  
    dfs(edge[i].to,v);  
}  
int main ()  
{  
    int n,m,u,v,p;  
    int src,des;  
    int sum;  
    while (scanf("%d %d",&n,&m)!=EOF)  
    {  
        ep = 0;  
        sum=0;  
        src = 0;  
        des = n + 1;  
        memset (head,-1,sizeof(head));  
        for(int i=1;i<=n;i++)  
        {  
            scanf("%d",&p);  
            if(p>0)  
            {  
                addedge(src,i,p);  
                sum+=p;  
            }  
            else  
            addedge(i,des,-p);  
        }  
        for (int i=1; i<=m; i++)  
        {  
            scanf("%d%d",&u,&v);  
            addedge(u,v,inf);  
        }  
        int max_flow=sap(src,des,n + 2);;  
  
        printf("%d\n",sum-max_flow);  
    }  
    return 0;  
}  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值