HDU多校--Harmonious Army--最小割建模

 

Harmonious Army

Time 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.

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 v have 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

 

若兩者都選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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章