posts - 7,comments - 3,trackbacks - 0
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, 
0sizeof(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, 
-1sizeof(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 + 21-c);
        }
        
for (int i = 0; i <= 401++i)
            add_edge(i, i 
+ 120);
        
int ans = mcmf(0402);
        printf(
"%d\n"-ans);
    }
}
posted on 2011-10-15 22:20 LLawliet 阅读(72) 评论(0)  编辑 收藏 引用 所属分类: 网络流

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理