题意:n个任务,两个机器AB,输入n对数字Ai Bi

表示i号任务在A上消耗和在B上的消耗。

然后再给m行,每行a,b,c三个数字。

表示如果a任务和b任务不在一个机器上工作的话,需要额外花费c。

问,所有任务都工作的情况下,最小的花费是多少。

做法:

说来话长,这个题我想了好多种连边的方法,每个点拆两个点啊三个点啊,假设只有两个点m=1时挨个试了都不对QAQ原来根本就不用拆!

左边和源点连a流量,右边和汇点连b流量,m对边来回连w流量。

其实一开始是想到这个方法的,但是自己把自己给否认了,原因:

假设只有两个点a1=2 b1=10 a2=10 b2=2 a->b w=12 这个时候我本以为应该走a1 b2那条路,然而最终答案是14,体现不出来额外加的w,但是流量是如图这么走的:

这么看图我是死活都没解释出来流量和w有毛线关系QAQ

但是12=a1+a2=b1+b2说明这个时候你就可以认为是两种机器在同一侧了!就这个图来说,w继续增加说服力更强!当w很大的时候,我们肯定是不会让给机器不在同一侧的!反过来想,如果w变小,看下面的两张图,差的流量(就是你认为不应该有的部分)是哪里来的?反向流加的……右边的图就可以理解成是2+7所得到的




/**************
poj3469
2016.8.10
10864K	4704MS	C++	1932B
**************/
#include <stdio.h>
#include<cstring>
#include <iostream>
using namespace std;
const int oo=0x3f3f3f3f;
const int mm=900000;
const int mn=900000;
int node ,scr,dest,edge;
int ver[mm],flow[mm],next[mm];
int head[mn],work[mn],dis[mn],q[mn];
void prepare(int _node,int _scr,int _dest)
{
    node=_node,scr=_scr,dest=_dest;
    for(int i=0; i<node; ++i)
        head[i]=-1;
    edge=0;
}
void addedge(int u,int v,int c)
{
    ver[edge]=v,flow[edge]=c,next[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,next[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
    int i,u,v,l,r=0;
    for(i=0; i<node; i++)
        dis[i]=-1;
    dis[q[r++]=scr]=0;
    for(l=0; l<r; ++l)
    {
        for(i=head[u=q[l]]; i>=0; i=next[i])
        {
            if(flow[i]&&dis[v=ver[i]]<0)
            {
                dis[q[r++]=v]=dis[u]+1;
                if(v==dest)
                    return 1;
            }
        }
    }
    return 0;
}
int Dinic_dfs(int u,int exp)
{
    if(u==dest)
        return exp;
    for(int &i=work[u],v,tmp; i>=0; i=next[i])
        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
        {
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            return tmp;
        }
    return 0;
}
int Dinic_flow()
{
    int i,ret=0,delta;
    while(Dinic_bfs())
    {
        for(i=0; i<node; i++)
            work[i]=head[i];
        while(delta=Dinic_dfs(scr,oo))
            ret+=delta;
    }
    return ret;
}
int n,m;
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        prepare(n+2,0,n+1);
        for(int i=1;i<=n;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            addedge(0,i,a);
            addedge(i,n+1,b);
        }
        while(m--)
        {
            int a,b,w;
            scanf("%d%d%d",&a,&b,&w);
            addedge(a,b,w);
            addedge(b,a,w);
        }
        printf("%d\n",Dinic_flow());
    }
    return 0;
}