JOJ2726:PLAN

来源:互联网 发布:怎么用阿里云建立免流 编辑:程序博客网 时间:2024/05/13 10:27
2726 Plan
FJ has two same house for rant. Now he has n (1 ≤ n ≤ 1000) piece of order, the orders are 
given in the form: 
s t v
means that someone want to rant a house from the day s to t paying v yuan totally (including 
the day s and t, 0 ≤ s ≤ t ≤ 400, 0 ≤ v ≤ 100,0000). 
A hours can be only rant to one person, and FJ should either accept an order totally or reject it. 
Input
The first line of input file is a single integer T - The number of test cases. For each test case, 
the first line is a single integer n then there n lines, each line gives an order
Output
For each data set, print a single line containing an integer, the maximum total income for the 
data set
Sample Input
3
4
1 2 10
2 3 10
3 3 10
1 3 10
6
1 20 1000
3 25 10000
5 15 5000
22 300 5500
10 295 9000
7 7 6000
8
32 251 2261
123 281 1339
211 235 5641
162 217 72736
22 139 7851
194 198 9190
119 274 878
122 173 8640
Sample Output
30
25500
38595



唐牛春季网络流专场的一道题,今天做了一下。
发现最小费用流就能搞定,定义完数组发现如果以order为点肯定超时了,所以re看了一下题,发现t的范围很小,都是整数,所以果断改图,把每秒作为点就OK了。
建图方法:相邻两个点(t,t + 1)连线,流量是2,费用是0,对于每一个order,s + 1和t + 2连线(t + 2多加1是因为防止有起始点与它相同,出现流错误)流量为1,费用为-c,在这个图上做一边最小费用流就行了。
SPFA很犀利,不过极限数据还是跑不进0.00s.....
代码:
#include <cstdio>
#include <cstring>
#define min(a, b) (a > b ? b : a)
using namespace std;

const int maxn = 405;
const int maxm = 3300;
const int inf = 1 << 30;
int n;

struct Edge
{
    int v, next, c, w;
} edge[maxm];

int head[maxn], cnt;

void add_edge(int u, int v, int w, int c)
{
    edge[cnt].v = v;
    edge[cnt].w = w;
    edge[cnt].c = c;
    edge[cnt].next = head[u];
    head[u] = cnt++;

    edge[cnt].v = u;
    edge[cnt].w = 0;
    edge[cnt].c = -c;
    edge[cnt].next = head[v];
    head[v] = cnt++;
}

int dis[maxn], pre[maxn];
int alpha[maxn];
int que[maxn], qhead, qrear;

int spfa(int s, int e)
{
    for (int i = 0; i < maxn; ++i)
        dis[i] = inf;
    memset(alpha, 0, sizeof(alpha));
    dis[s] = 0;
    que[qhead = 0] = s;
    qrear = 1;
    alpha[s] = 1;
    while (qhead != qrear)
    {
        int k = que[qhead++];
        qhead %= maxn;
        alpha[k] = 0;
        for (int q = head[k]; ~q; q = edge[q].next)
            if (edge[q].w)
                if (dis[k] + edge[q].c < dis[edge[q].v])
                {
                    dis[edge[q].v] = dis[k] + edge[q].c;
                    pre[edge[q].v] = q;
                    if (!alpha[edge[q].v])
                    {
                        alpha[edge[q].v] = true;
                        if (edge[q].c < 0)
                        {
                            qhead = (qhead - 1 + maxn) % maxn;
                            que[qhead] = edge[q].v;
                        }
                        else
                        {
                            que[qrear++] = edge[q].v;
                            qrear %= maxn;
                        }
                    }
                }
    }
    if (dis[e] == inf) return -1;
    int k = inf;
    for (int i = e; i != s; i = edge[pre[i] ^ 1].v)
       k = min(k, edge[pre[i]].w);
    return k;
}

int mcmf(int s, int t)
{
    int ans = 0, k;
    while (~(k = spfa(s, t)))
    {
        for (int i = t; i != s; i = edge[pre[i] ^ 1].v)
        {
            edge[pre[i]].w -= k;
            edge[pre[i] ^ 1].w += k;
        }
        ans += dis[t] * k;
    }
    return ans;
}

void init()
{
    cnt = 0;
    memset(head, -1, sizeof(head));
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T--)
    {
        init();
        scanf("%d", &n);
        for (int i = 0; i < n; ++i)
        {
            int a, b, c;
            scanf("%d%d%d", &a, &b, &c);
            add_edge(a + 1, b + 2, 1, -c);
        }
        for (int i = 0; i <= 401; ++i)
            add_edge(i, i + 1, 2, 0);
        int ans = mcmf(0, 402);
        printf("%d\n", -ans);
    }
}

原创粉丝点击