HDU6598 Harmoinious Army(最大流)
/* * hdu6598 * 题意: * n个士兵,m个组合 * 每个士兵可以专职战士或者魔法师 * u和v组合,两个战士战力+a,两个法师战力+c,其他战力+b * 求解最多加多少战力 * 题解: * 经典网络流模型。 * 对每个士兵建立一个点x,点x向源点s连一条边,向汇点t连一条边。 * 分别表示选择两种职业,然后就可以加上所有的贡献,通过两点关系用最小割建模。 * 将所有有关系的两点的图合并,用所有的贡献剪掉这个图的最小割。 * */ #include<cstdio> #include<cstring> #include<algorithm> #include<queue> typedef long long ll; using namespace std; const int maxn=505; const int maxm=5e5+100; const ll inf=1e18; struct node { int u,v,next; ll w; }edge[maxm]; ll tol; ll head[maxn]; void addedge (int u,int v,ll w) { edge[tol].u=u; edge[tol].v=v; edge[tol].w=w; edge[tol].next=head[u]; head[u]=tol++; edge[tol].u=v; edge[tol].v=u; edge[tol].w=0; edge[tol].next=head[v]; head[v]=tol++; } ll dep[maxn]; ll inque[maxn]; ll vi; ll cur[maxn]; ll maxflow=0; void init () { memset(head,-1,sizeof(head)); tol=0; memset(dep,0,sizeof(dep)); memset(inque,0,sizeof(inque)); memset(cur,0,sizeof(cur)); vi=0; maxflow=0; } int N,M; int s,t; bool bfs () { for (int i=0;i<=N;i++) cur[i]=head[i],dep[i]=inf,inque[i]=0; dep[s]=0; queue<int> q; q.push(s); while (!q.empty()) { int u=q.front(); q.pop(); inque[u]=0; for (int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if (dep[v]>dep[u]+1&&edge[i].w) { dep[v]=dep[u]+1; if (inque[v]==0) { q.push(v); inque[v]=1; } } } } if (dep[t]!=inf) return 1; return 0; } ll dfs (int u,ll flow) { ll increase=0; if (u==t) { vi=1; maxflow+=flow; return flow; } ll used=0; for (int i=cur[u];i!=-1;i=edge[i].next) { cur[u]=i; int v=edge[i].v; if (edge[i].w&&dep[v]==dep[u]+1) { if (increase=dfs(v,min(flow-used,edge[i].w))) { used+=increase; edge[i].w-=increase; edge[i^1].w+=increase; if (used==flow) break; } } } return used; } ll Dinic () { while (bfs()) { vi=1; while (vi==1) { vi=0; dfs(s,inf); } } return maxflow; } int main () { while (~scanf("%d%d",&N,&M)) { init(); ll u,v,a,b,c; ll A,C,E; s=0,t=++N; ll sum=0;; for (int i=1;i<=M;i++) { scanf("%lld%lld%lld%lld%lld",&u,&v,&a,&b,&c); a*=2; b*=2; c*=2; sum+=a+b+c; A=(a+b)/2; C=(c+b)/2; E=-b+(a+c)/2; addedge(s,u,A); addedge(s,v,A); addedge(u,t,C); addedge(v,t,C); addedge(u,v,E); addedge(v,u,E); } ll ans=Dinic(); printf("%lld\n",(sum-ans)/2); //printf("1\n"); } }