网络最大流

题目
code

#include 
#include 
#include 
#include 
using namespace std;
typedef long long ll;
const int N=1e4+5;
const int M=2e5+5;
struct node
{
    ll y,w,nxt;
};
node Edge[M<<1];
ll head[N],cnt=1;
ll n,m,s,t;
ll dep[N];
void Add(int x,int y,int w)
{
    cnt++;
    Edge[cnt].y=y;
    Edge[cnt].w=w;
    Edge[cnt].nxt=head[x];
    head[x]=cnt;
    return;
}
bool bfs()
{
    memset(dep,0,sizeof(dep));
    dep[s]=1;
    queue<ll> q;
    q.push(s);
    while(!q.empty())
    {
        ll now=q.front();
        q.pop();
        for(int i=head[now];~i;i=Edge[i].nxt)
        {
            ll y=Edge[i].y;
            if(Edge[i].w!=0&&dep[y]==0)
            {
                dep[y]=dep[now]+1;
                q.push(y);
            }
        }
    }
    return dep[t];
}
ll dinic(ll x,ll flow)
{
    if(x==t) return flow;
    ll sum=0;
    for(int i=head[x];~i;i=Edge[i].nxt)
    {
        if(Edge[i].w&&dep[Edge[i].y]==dep[x]+1)
        {
            ll tmp=dinic(Edge[i].y,min(flow,Edge[i].w));
            flow-=tmp;
            sum+=tmp;
            Edge[i].w-=tmp;
            Edge[i^1].w+=tmp;
        }
    }
    if(sum==0) return dep[x]=0;
    return sum;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    cin>>n>>m>>s>>t;
    ll x,y,w,i;
    memset(head,-1,sizeof(head));
    for(i=0;i<m;i++)
    {
        cin>>x>>y>>w;
        Add(x,y,w);
        Add(y,x,0);
    }
    ll ans=0;
    while(true)
    {
        if(!bfs()) break;
        ans+=dinic(s,0x3f3f3f3f);
    }
    cout<<ans<<endl;
    return 0;
}

按位异或运算符“^”是双目运算符。当两对应的二进位相异时,结果为1。
2(10),1(01);2^1=3(11);
3(11),1(01);3^1=2(10);
所以从2开始,加边,两条反边相邻,任意一条边^1可以的得到其反边。

你可能感兴趣的:(算法)