题意:略

各点向原信念连INF+1的边,不同信念连INF的边,这样割原信念花费大一点。然后好友连1的边。最小割的结果-n*INF就是答案,因为割到哪边最少都要INF。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-12;
typedef long long lon;
const lon SZ=320,SSZ=5005,APB=10000,one=1,INF=0x7FFFFFFF,mod=1000000007;
int n,m,S=305,T=306,dep[SZ];
int mp[SZ][SZ];

void add(int u,int v,int w)
{
    mp[u][v]=w;
}

void init()
{
    for(int i=1;i<=n;++i)
    {
        int tmp;
        cin>>tmp;
        if(!tmp)
        {
            add(S,i,APB+1);
            add(i,S,0);
            add(i,T,APB);
            add(T,i,0);
        }
        else
        {
            add(S,i,APB);
            add(i,S,0);
            add(i,T,APB+1);
            add(T,i,0);
        }
    }
    for(int i=1;i<=m;++i)
    {
        int a,b;
        cin>>a>>b;
        add(a,b,1);
        add(b,a,1);
    }
}

bool bfs()
{
    memset(dep,0,sizeof(dep));
    dep[S]=1;
    queue<int> q;
    q.push(S);
    for(;q.size();)
    {
        int fr=q.front();
        q.pop();
        for(int i=1;i<=T;++i)
        {
            if(!dep[i]&&mp[fr][i])
            {
                dep[i]=dep[fr]+1;
                q.push(i);
                if(i==T)return 1;
            }
        }
    }
    return 0;
}

int dinic(int x,int flow)
{
    if(x==T)return flow;
    else
    {
        int rem=flow;
        for(int i=1;i<=T&&rem;++i)
        {
            if(dep[i]==dep[x]+1&&mp[x][i])
            {
                int tmp=dinic(i,min(rem,mp[x][i]));
                if(!tmp)dep[i]=0;
                rem-=tmp;
                mp[x][i]-=tmp,mp[i][x]+=tmp;
            }
        }
        return flow-rem;
    }
}

void work()
{
    int res=0;
    for(;bfs();)res+=dinic(S,INF);
    cout<<res-n*APB<<endl;
}

void release()
{
    memset(mp,0,sizeof(mp));
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    //cout<<(1<<31)<<endl;
    int casenum;
    //cin>>casenum;
    //cout<<casenum<<endl;
    //for(int time=1;time<=casenum;++time)
    for(int time=1;cin>>n>>m,n;++time)
    {
        init();
        work();
        release();
    }
    return 0;
}

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄