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