ACM-ICPC 2018 焦作赛区网络预赛 F. Modular Production Line (区间K覆盖-最小费用流)

很明显的区间K覆盖模型,用费用流求解.只是这题N可达1e5,需要将点离散化.

建模方式步骤:

1.对权值为w的区间[u,v],加边id(u)->id(v+1),容量为1,费用为-w;

2.对所有相邻的点加边id(i)->id(i+1),容量为正无穷,费用为0;

3.建立源点汇点,由源点s向最左侧的点加边,容量为K,费用为0,由最右侧的点向汇点加边,容量为K,费用为0

4.跑出最大流后,最小费用取绝对值就是能获得的最大权

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1000;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
struct Edge{
    int to, next, cap, flow, cost;
} edge[MAXM];
int head[MAXN], tol;
int pre[MAXN], dis[MAXN];
bool vis[MAXN];
int N;
void init(int n)
{
    N = n;
    tol = 0;
    memset(head, -1, sizeof(head));
}

void addedge(int u, int v, int cap, int cost)
{
    edge[tol].to = v;
    edge[tol].cap = cap;
    edge[tol].cost = cost;
    edge[tol].flow = 0;
    edge[tol].next = head[u];
    head[u] = tol++;
    edge[tol].to = u;
    edge[tol].cap = 0;
    edge[tol].cost = -cost;
    edge[tol].flow = 0;
    edge[tol].next = head[v];
    head[v] = tol++;
}

bool spfa(int s, int t){
    queue<int> q;
    for (int i = 0; i < N; i++){
        dis[i] = INF;
        vis[i] = false;
        pre[i] = -1;
    }
    dis[s] = 0;
    vis[s] = true;
    q.push(s);
    while (!q.empty()){
        int u = q.front();
        q.pop();
        vis[u] = false;
        for (int i = head[u]; i != -1; i = edge[i].next){
            int v = edge[i].to;

            if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost){
                dis[v] = dis[u] + edge[i].cost;
                pre[v] = i;
                if (!vis[v]){
                    vis[v] = true;
                    q.push(v);
                }
            }
        }
    }
    if (pre[t] == -1) return false;
    else  return true;
}

int minCostMaxflow(int s, int t, int &cost){
    int flow = 0;
    cost = 0;
    while (spfa(s, t)){
        int Min = INF;
        for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){
            if (Min > edge[i].cap - edge[i].flow)
                Min = edge[i].cap - edge[i].flow;
        }
        for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to]){
            edge[i].flow += Min;
            edge[i ^ 1].flow -= Min;
            cost += edge[i].cost * Min;
        }
        flow += Min;
    }
    return flow;
}

map<int,int> dp;
struct edg{
    int u,v,w;
}ed[MAXN];

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int T,N,M,K,u,v,w;
    scanf("%d",&T);
    map<int,int> ::iterator it;
    while(T--){
        dp.clear();
        scanf("%d %d %d",&N, &K, &M);
        for(int i=1;i<=M;++i){
            scanf("%d %d %d",&u,&v,&w);
            v++;
            ed[i] = (edg){u,v,w};
            dp[u] = dp[v] = 1;
        }
        int cnt=0;
        for(it = dp.begin();it!=dp.end();++it){
            int id = it->first;
            dp[id] =  ++cnt;
        }
        init(cnt+5);
        int s = 0,t = cnt+1;
        addedge(s,1,K,0);
        addedge(cnt,t,K,0);
        for(int i=1;i<cnt;++i){
            addedge(i,i+1,INF,0);
        }
        for(int i=1;i<=M;++i){
            u = ed[i].u, v = ed[i].v;
            u = dp[u], v =dp[v];
            addedge(u,v,1,-ed[i].w);
        }
        int cost;
        minCostMaxflow(s,t,cost);
        printf("%d\n",-cost);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xiuwenli/p/9651790.html

时间: 2024-08-24 17:47:11

ACM-ICPC 2018 焦作赛区网络预赛 F. Modular Production Line (区间K覆盖-最小费用流)的相关文章

ACM-ICPC 2018 焦作赛区网络预赛 B题 Mathematical Curse

A prince of the Science Continent was imprisoned in a castle because of his contempt for mathematics when he was young, and was entangled in some mathematical curses. He studied hard until he reached adulthood and decided to use his knowledge to esca

ACM-ICPC 2018 焦作赛区网络预赛 H题 String and Times(SAM)

Now you have a string consists of uppercase letters, two integers AA and BB. We call a substring wonderful substring when the times it appears in that string is between AA and BB (A \le times \le BA≤times≤B). Can you calculate the number of wonderful

ACM-ICPC 2018 焦作赛区网络预赛 L 题 Poor God Water

God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him that some sequence of eating will make them poisonous. Every hour, God Water will eat one kind of food among meat, fish and chocolate. If there are 33 

ACM-ICPC 2018 焦作赛区网络预赛 K题 Transport Ship

There are NN different kinds of transport ships on the port. The i^{th}ith kind of ship can carry the weight of V[i]V[i] and the number of the i^{th}ith kind of ship is 2^{C[i]} - 12C[i]?1. How many different schemes there are if you want to use thes

ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph

"Oh, There is a bipartite graph.""Make it Fantastic." X wants to check whether a bipartite graph is a fantastic graph. He has two fantastic numbers, and he wants to let all the degrees to between the two boundaries. You can pick up sev

ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (贪心)

分析:贪心地删边后检查每个点的度即可,这也是正确的做法? #include <bits/stdc++.h> using namespace std; const int MAXN = 1e4+5; struct Edge{ int u,v,next; }edges[MAXN<<2]; int head[MAXN],tot; int deg[MAXN]; void init() { memset(head,-1,sizeof(head)); tot =0 ; memset(deg,0

ACM-ICPC 2018 焦作赛区网络预赛 L:Poor God Water(矩阵快速幂)

God Water likes to eat meat, fish and chocolate very much, but unfortunately, the doctor tells him that some sequence of eating will make them poisonous. Every hour, God Water will eat one kind of food among meat, fish and chocolate. If there are 3 c

ACM-ICPC 2018 焦作赛区网络预赛 E. Jiu Yuan Wants to Eat (树链剖分-线性变换线段树)

树链剖分若不会的话可自行学习一下. 前两种操作是线性变换,模\(2^{64}\)可将线段树全部用unsigned long long 保存,另其自然溢出. 而取反操作比较不能直接处理,因为其模\(2^{64}\)的特殊性,可将其转化为线性变换. 显然 \[-x\equiv (2^{64}-1)*x (mod\ 2^{64})\] 因为\[!x = (2^{64}-1) -x \] 所以 \[ !x = (2^{64}-1) + (2^{64}-1)x\] #include<bits/stdc++

ACM-ICPC 2018 焦作赛区网络预赛 B. Mathematical Curse &lt;&lt; DP

题意 有n个数和m个运算符,按顺序选m个数进行运算,初值为k,问最后能得到的最大值是多少. 思路 dp[i][j]表示选到了第i个数时用了j个运算符,观察发现,一个数只能由他前一个状态的最大值或最小值转移过来(因为乘上一个负数会使最小的数变最大),所以我们同时维护最大最小. 然后转移就行了,需要注意$i-1>j$时是不合法的状态. 转移方程:$dp[i][j]=max(dp[i-1][j-1]\circ now[i],dp[i-1][j])(i<j)$ 代码 1 #include<bit