【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 }

 

posted on 2019-09-25 20:04  myx12345  阅读(170)  评论(0编辑  收藏  举报

导航