【HDOJ6598】Harmonious Army(最小割)
题意:有n个人,每个人可以从A,B两种职业中选择一种
有m对两人组,如果两个人都是A能获得p的收益,一个A一个B能获得q的收益,都是B能获得r的收益,其中q=p/4+r/3,保证p%4=0,r%3=0
求最大总收益
n<=5e2,m<=1e4,p,q,r<=4e6
思路:主要是建图
求得一组等效解,答案即为所有边权之和减去最小割
S出发到i的流量总数和i出发到T的流量总数可以累加一下最后再加这两种边,边数可以少一点
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef pair<int,int> PII; 7 typedef pair<ll,ll> Pll; 8 typedef vector<int> VI; 9 typedef vector<PII> VII; 10 typedef pair<ll,ll>P; 11 #define N 100010 12 #define M 200010 13 #define fi first 14 #define se second 15 #define MP make_pair 16 #define pi acos(-1) 17 #define mem(a,b) memset(a,b,sizeof(a)) 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 20 #define lowbit(x) x&(-x) 21 #define Rand (rand()*(1<<16)+rand()) 22 #define id(x) ((x)<=B?(x):m-n/(x)+1) 23 #define ls p<<1 24 #define rs p<<1|1 25 26 const ll MOD=1e9+7,inv2=(MOD+1)/2; 27 double eps=1e-4; 28 ll INF=1ll<<60; 29 ll inf=5e13; 30 int dx[4]={-1,1,0,0}; 31 int dy[4]={0,0,-1,1}; 32 33 int head[N],vet[N],nxt[N],dis[N],gap[N],fan[N],s,S,T,tot; 34 ll a[N][2]; 35 double len[N]; 36 37 int read() 38 { 39 int v=0,f=1; 40 char c=getchar(); 41 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 42 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 43 return v*f; 44 } 45 46 void add(int a,int b,double c) 47 { 48 nxt[++tot]=head[a]; 49 vet[tot]=b; 50 len[tot]=c; 51 head[a]=tot; 52 53 nxt[++tot]=head[b]; 54 vet[tot]=a; 55 len[tot]=0; 56 head[b]=tot; 57 } 58 59 double dfs(int u,double aug) 60 { 61 if(u==T) return aug; 62 int e=head[u],val=s-1; 63 double flow=0; 64 while(e) 65 { 66 int v=vet[e]; 67 if(len[e]) 68 { 69 if(dis[u]==dis[v]+1) 70 { 71 double t=dfs(v,min(len[e],aug-flow)); 72 len[e]-=t; 73 len[fan[e]]+=t; 74 flow+=t; 75 if(dis[S]>=s) return flow; 76 if(aug==flow) break; 77 } 78 val=min(val,dis[v]); 79 } 80 e=nxt[e]; 81 } 82 if(!flow) 83 { 84 gap[dis[u]]--; 85 if(!gap[dis[u]]) dis[S]=s; 86 dis[u]=val+1; 87 gap[dis[u]]++; 88 } 89 return flow; 90 } 91 92 double maxflow() 93 { 94 rep(i,0,s) gap[i]=dis[i]=0; 95 gap[0]=s; 96 double ans=0; 97 while(dis[S]<s) ans+=dfs(S,INF); 98 return ans; 99 } 100 101 int main() 102 { 103 rep(i,1,N-1) 104 if(i&1) fan[i]=i+1; 105 else fan[i]=i-1; 106 int n,m; 107 while(scanf("%d%d",&n,&m)!=EOF) 108 { 109 s=n; 110 S=++s; T=++s; 111 tot=0; 112 rep(i,1,s) head[i]=0; 113 rep(i,1,n) a[i][0]=a[i][1]=0; 114 ll ans=0; 115 rep(i,1,m) 116 { 117 int x=read(),y=read(),p=read(),q=read(),r=read(); 118 a[x][0]+=p+q; 119 a[y][0]+=p+q; 120 a[x][1]+=q+r; 121 a[y][1]+=q+r; 122 add(x,y,(p+r-2*q)/2.0); 123 add(y,x,(p+r-2*q)/2.0); 124 ans+=p+q+r; 125 } 126 rep(i,1,n) 127 { 128 add(S,i,a[i][0]/2.0); 129 add(i,T,a[i][1]/2.0); 130 } 131 ans=(ll)ans-maxflow(); 132 printf("%I64d\n",ans); 133 } 134 135 136 return 0; 137 }
null