题解:

最小割

见图

代码:

#include<bits/stdc++.h>   
const int N=600005;  
using namespace std;  
struct edge_type{int next,to,v;}e[N];  
int fi[N],cur[N],dis[N],n,m,s,t,cnt=1,ans=0,x,y,z;  
void jb(int x,int y,int v)  
{  
    e[++cnt]=(edge_type){fi[x],y,v};fi[x]=cnt;  
    e[++cnt]=(edge_type){fi[y],x,0};fi[y]=cnt;  
}  
int bfs()  
{  
    queue<int>q;  
    memset(dis,-1,sizeof(dis));  
    dis[s]=0;q.push(s);  
    while (!q.empty())  
     {  
        int tmp=q.front();q.pop();  
        if (tmp==t) return 1;  
        for (int i=fi[tmp];i;i=e[i].next)
         if (e[i].v&&dis[e[i].to]==-1)  
          {  
            dis[e[i].to]=dis[tmp]+1;  
            q.push(e[i].to);  
          }  
    }  
    return 0;  
}  
int dfs(int x,int f)  
{  
    int tmp,sum=0;  
    if (x==t) return f;  
    for (int &i=cur[x];i;i=e[i].next)  
     {  
        int y=e[i].to;  
        if (e[i].v&&dis[y]==dis[x]+1)  
         {  
            tmp=dfs(y,min(f-sum,e[i].v));  
            e[i].v-=tmp;e[i^1].v+=tmp;sum+=tmp;  
            if (sum==f) return sum;  
         }  
     }  
    if (!sum) dis[x]=-1;  
    return sum;  
}  
void dinic()  
{  
    while (bfs())  
     {  
        for (int i=1;i<=t;i++) cur[i]=fi[i];  
        ans-=dfs(s,1e9);  
     }  
}  
int main()  
{  
       scanf("%d%d",&n,&m); 
    s=n+m+1;t=s+1;
    for (int i=1;i<=n;i++)
     {  
        scanf("%d",&z);
        jb(i+m,t,z);
     }  
    for (int i=1;i<=m;i++)
     {  
        scanf("%d%d%d",&x,&y,&z);  
        ans+=z;  
        jb(s,i,z);  
        jb(i,x+m,1e9);
        jb(i,y+m,1e9);  
     }  
    dinic();  
    printf("%d\n",ans);  
}  

 

posted on 2018-02-07 14:05  宣毅鸣  阅读(97)  评论(0编辑  收藏  举报