Harmonious Army
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1280 Accepted Submission(s): 464
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.
Note that the symbol a|b means that a divides b, e.g. , 3|12 and 8|24.
Input
There are multiple test cases.
Each case starts with a line containing two positive integers n(n≤500) and m(m≤104).
In the following m lines, each line contains five positive integers u,v,a,b,c (1≤u,v≤n,u≠v,1≤a,c≤4×106,b=a/4+c/3), denoting soldiers u and vhave combination ability, guaranteed that the pair (u,v) would not appear more than once.
It is guaranteed that the sum of n in all test cases is no larger than 5×103, and the sum of m in all test cases is no larger than 5×104.
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
Statistic | Submit | Discuss | Note
题目大意:n个士兵,给出了m个关系,分别有三个权值abc,分别代表 如果两个士兵同时在A组则会产生a的贡献,
如果同时在B组则会产生c的贡献,否则产生b的贡献。
解题思路:跟poj3469比较像,本题求的是最大贡献,我们可以转化为最小割问题,让答案减去最小割即可。
建图方式如上图所示:
如果割掉ax和bx 代表x和y同时在B组,花费为 ax+bx=B+C
如果割掉ay和by代表x和y同时在B组,花费为 ay+by=A+B
同理还有x和y不在同一组还要割掉w。
我们用总的贡献减去最小花费即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define LL long long
#define N 505
#define maxn 300005
#define inf 0x3f3f3f3f
#define sca(x) scanf("%d",&x)
struct edg
{
int to,nt,w;
}g[maxn];
struct node
{
int tot;
int head[N],cur[N],dep[N];
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
void addedg(int x,int y,int w)
{
g[tot].to=y;
g[tot].w=w;
g[tot].nt=head[x];
head[x]=tot++;
g[tot].to=x;
g[tot].w=0;
g[tot].nt=head[y];
head[y]=tot++;
}
bool spfa(int s,int t)
{
memset(dep,0,sizeof(dep));
dep[s]=1;
queue<int>q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i+1;i=g[i].nt)
{
int v=g[i].to;
if(dep[v]==0&&g[i].w>0)
{
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return dep[t]>0;
}
int dfs(int s,int t,int flow)
{
if(s==t)return flow;
int tmp=0;
for(int &i=cur[s];i+1;i=g[i].nt)
{
int v=g[i].to;
if(dep[v]==dep[s]+1&&g[i].w>0&&
(tmp=dfs(v,t,min(flow,g[i].w))))
{
g[i].w-=tmp;
g[i^1].w+=tmp;
return tmp;
}
}
return 0;
}
LL dinic(int s,int t)
{
LL ans=0;
int tmp=0;
while(spfa(s,t))
{
memcpy(cur,head,sizeof(head));
while(tmp=dfs(s,t,inf))
{
ans+=tmp;
}
}
return ans;
}
}din;
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
int s=0,t=n+1;
din.init();
LL ans=0;
for(int i=1;i<=m;i++)
{
int u,v,a,b,c;
scanf("%d%d%d%d%d",&u,&v,&a,&b,&c);
ans+=(a+b+c);
din.addedg(s,u,b+c);
din.addedg(u,t,a+b);
din.addedg(s,v,b+c);
din.addedg(v,t,a+b);
din.addedg(u,v,a+c-2*b);
din.addedg(v,u,a+c-2*b);
}
printf("%lld\n",ans-din.dinic(s,t)/2);
}
}