Harmonious ArmyTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1493 Accepted Submission(s): 546 Problem Description Now, Bob is playing an interesting game in which he is a general of a harmonious army. There are n soldiers in this army. Each soldier should be in one of the two occupations, Mage or Warrior. There are m pairs of soldiers having combination ability. There are three kinds of combination ability. If the two soldiers in a pair are both Warriors, the army power would be increased by a . If the two soldiers in a pair are both Mages, the army power would be increased by c . Otherwise the army power would be increased by b , and b=a/4+c/3 , guaranteed that 4|a and 3|c . Your task is to output the maximum power Bob can increase by arranging the soldiers' occupations.
Input There are multiple test cases.
Output For each test case, output one line containing the maximum power Bob can increase by arranging the soldiers' occupations.
Sample Input 3 2 1 2 8 3 3 2 3 4 3 6
Sample Output 12
Source 2019 Multi-University Training Contest 2
Recommend liuyiding
|
若两者都选S a+b=A+C
若两者都选T c+d=B+C
其他两者情况为 a+e+d=A+C b+e+c=A+C
那么连立解出a...e。
经典最小割建模
https://www.cnblogs.com/chenyushuo/p/5146626.html
#include <algorithm> //STL通用算法
#include <bitset> //STL位集容器
#include <cmath>
#include <cstdio>
#include <cstring>
#include <deque> //STL双端队列容器
#include <exception> //异常处理类
#include <fstream>
#include <functional> //STL定义运算函数(代替运算符)
#include <limits>
#include <list> //STL线性列表容器
#include <map> //STL 映射容器
#include <iomanip>
#include <ios> //基本输入/输出支持
#include<iosfwd> //输入/输出系统使用的前置声明
#include <iostream>
#include <istream> //基本输入流
#include <ostream> //基本输出流
#include <queue> //STL队列容器
#include <set> //STL 集合容器
#include <sstream> //基于字符串的流
#include <stack> //STL堆栈容器
#include <string> //字符串类
#include <vector> //STL动态数组容器
#define ll long long
using namespace std;
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
//priority_queue<int,vector<int>,less<int> >q;
int dx[]= {-1,1,0,0,-1,-1,1,1};
int dy[]= {0,0,-1,1,-1,1,1,-1};
const int maxn = 500+66;
const int maxm=400000+66;
const ll mod=1e9+7;
typedef pair<ll, int> P;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int n, m, cas;
ll d[maxn];
struct GDJ
{
int head[maxn], cnt;
int to[maxm], nxt[maxm];
ll val[maxm];
void init()
{
rep(i,0,n+3)head[i]=-1;
//memset(head, -1, (n + 5) * sizeof(int));
cnt = -1;
}
void ade(int a, int b, ll c)
{
to[++cnt] = b;
nxt[cnt] = head[a];
val[cnt] = c;
head[a] = cnt;
}
bool vis[maxn];
void dj(int s)
{
priority_queue<P, vector<P>, greater<P> > que;
memset(d, 0x3f, (n + 5) * sizeof(ll));
memset(vis, 0, (n + 5) * sizeof(bool));
d[s] = 0;
que.push(P(0, s));
while(!que.empty())
{
P p = que.top();
que.pop();
int u = p.second;
if(vis[u])
continue;
vis[u] = 1;
for(int i = head[u]; ~i; i = nxt[i])
{
int v = to[i];
if(d[v] > d[u] + val[i])
{
d[v] = d[u] + val[i];
que.push(P(d[v], v));
}
}
}
}
} DJ;
struct GDC
{
int depth[maxn], cur[maxn], head[maxn], cnt;
int to[maxm], nxt[maxm];
ll val[maxm];
void init()
{
rep(i,0,n+3)head[i]=-1;
cnt = -1;
}
void ade(int a, int b, ll c)
{
to[++cnt] = b;
nxt[cnt] = head[a];
val[cnt] = c;
head[a] = cnt;
to[++cnt] = a;
nxt[cnt] = head[b];
val[cnt] = 0;
head[b] = cnt;
}
bool bfs()
{
queue<int> que;
que.push(0);
rep(i,0,n+3)depth[i]=0;
depth[0] = 1;
while(!que.empty())
{
int u = que.front();
que.pop();
for(int i = head[u]; ~i; i = nxt[i])
{
if(val[i] > 0 && depth[to[i]] == 0)
{
depth[to[i]] = depth[u] + 1;
que.push(to[i]);
}
}
}
if(depth[n+1])
return 1;
else
return 0;
}
ll dfs(int u, ll dist)
{
if(u > n)
return dist;
for(int &i = cur[u]; ~i; i = nxt[i])
{
if(depth[to[i]] == depth[u] + 1 && val[i] > 0)
{
ll tmp = dfs(to[i], min(dist, val[i]));
if(tmp > 0)
{
val[i] -= tmp;
val[i ^ 1] += tmp;
return tmp;
}
}
}
return 0;
}
ll dinic()
{
ll res =0, d;
while(bfs())
{
for(int i = 0; i <= n+2; i ++)
cur[i] = head[i];
while(d = dfs(0,INF))
{
res += d;
//cout<<res<<endl;
}
}
return res;
}
} DC;
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
int s=0;
int e=n+1;
ll sum=0;
DC.init();
//n+=1;
rep(i,1,m)
{
int u,v,a,b,c;
scanf("%d %d %d %d %d",&u,&v,&a,&b,&c);
//u++;
//v++;
sum+=a+b+c;
int A=(a+b);
int B=(c+b);
int C=-2*b+(a+c);
DC.ade(s,u,A);
DC.ade(s,v,A);
DC.ade(u,e,B);
DC.ade(v,e,B);
DC.ade(v,u,C);
DC.ade(u,v,C);
}
ll ans=(sum-DC.dinic()/2);
printf("%lld\n",ans);
// cout << DC.dinic() << endl;//跑最大流
}
return 0;
}