hdoj3138
题意:略
各点向原信念连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; }

更多精彩