2019 Multi-University Training Contest 2 Harmonious Army

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值