(beginer) 网络流(区间模型+最大费用流) UVA 1317 Concert Hall Scheduling

来源:互联网 发布:excel筛选出多个数据 编辑:程序博客网 时间:2024/06/05 21:00

You are appointed director of a famous concert hall, to save it from bankruptcy. The hall is very popular, and receives many requests to use its two fine rooms, but unfortunately the previous director was not very efficient, and it has been losing money for many years. The two rooms are of the same size and arrangement. Therefore, each applicant wishing to hold a concert asks for a room without specifying which. Each room can be used for only one concert per day.

In order to make more money, you have decided to abandon the previous fixed price policy, and rather let applicants specify the price they are ready to pay. Each application shall specify a period [i, j] and an asking price w, where i and j are respectively the first and last days of the period (1$ \le$i$ \le$j$ \le$365), and w is a positive integer in yen, indicating the amount the applicant is willing to pay to use a room for the whole period.

You have received applications for the next year, and you should now choose the applications you will accept. Each application should be either accepted for its whole period or completely rejected. Each concert should use the same room during the whole applied period.

Considering the dire economic situation of the concert hall, artistic quality is to be ignored, and you should just try to maximize the total income for the whole year by accepting the most profitable applications.

Input 

The input has multiple data sets, each starting with a line consisting of a single integer n, the number of applications in the data set. Then, it is followed by n lines, each of which represents one application with a period [i, j] and an asking price w yen in the following format.


i j w


A line containing a single zero indicates the end of the input.

The maximum number of applications in a data set is one thousand, and the maximum asking price is one million yen.

Output 

For each data set, print a single line containing an integer, the maximum total income in yen for the data set.

Sample Input 

41 2 102 3 103 3 101 3 1061 20 10003 25 100005 15 500022 300 550010 295 90007 7 6000832 251 2261123 281 1339211 235 5641162 217 727322 139 7851194 198 9190119 274 878122 173 86400

Sample Output 

302550038595

题意:你有个两个能举行音乐会的房间。你要在一年内以出租的方式经营这两件房间,你会接到一些单子,单子内容包括租用的时间段以及价钱,接单子的时候不能有时间上的冲突。你要尽可能盈利,不管他的音乐会的质量→_→ 

思路:这个题目如果只有一个房间,那么之间用最长路就行了,但是有两个房间,我们能用网络流,想象一下图中有两个流从第0天往第366天流,这个过程就是时间的经过和以及房间的选择。那么我开始构图,每一天都是一个点,然后按照时间的顺序连有向边,容量为2(两个房间),如果有一个订单[i,j](这个时候流可能会发生分歧)那么我们在第i天加一条容量为1的有向边指向第j+1天。如果选择了这条路径相当于是接了这个订单,那么房间在第j+1天之前都是被占用的,所以直接跳到第j+1天。把最小费用最大流的模板套上去,把最短路改成最长路就行了。这个有向图没有环,不怕死循环的。

代码:
#include<iostream>
#include<cstring>
#include<string.h>
#include<vector>
#include<queue>
using namespace std;
const int inf = 1e8;
const int maxn = 365+5;
int q;
int d[maxn] , a[maxn];
bool inq[maxn];
int p[maxn];

struct Edge
{
int u , v , cost;
int flow , cap;
Edge(int uu,int vv,int ff,int ct,int cp) : u(uu) , v(vv) , flow(ff) , cap(cp) , cost(ct) { }
};

vector<Edge> edge;
vector<int> G[maxn];

void add(int s,int t,int cap,int cost)
{
edge.push_back(Edge(s,t,0,cost,cap));
edge.push_back(Edge(t,s,0,-cost,0));
int x = edge.size();
G[s].push_back(x-2);
G[t].push_back(x-1);
}

void input()
{
for (int i = 0 ; i < maxn ; ++i) G[i].clear();
edge.clear();
for (int i = 0 ; i <= 365 ; ++i) add(i,i+1,2,0);
int s , t , cost;
while (q--) {
scanf("%d%d%d",&s,&t,&cost);
add(s,t+1,1,cost);
}
}

bool spfa(int s,int t,int&flow,int&cost)
{
memset(inq,false,sizeof(inq));
memset(a,0x3f,sizeof(a));
memset(d,-1,sizeof(d));
queue<int> q; q.push(s);
inq[s] = true; d[s] = 0;
while (q.size()) {
int u = q.front(); q.pop();
inq[u] = false;
for (int i = 0 ; i < G[u].size() ; ++i) {
Edge & e = edge[G[u][i]];
if (e.cap > e.flow && d[e.v] < d[u]+e.cost) {
d[e.v] = d[u] + e.cost;
p[e.v] = G[u][i];
a[e.v] = min(a[u],e.cap-e.flow);
if (!inq[e.v]) { q.push(e.v); inq[e.v] = true; }
}
}
}
if (d[t]==-1) return false;
flow += a[t];
cost += d[t];
int x = t;
while (x!=s) {
edge[p[x]].flow += a[t];
edge[p[x]^1].flow -= a[t];
x = edge[p[x]].u;
}
return true;
}

int Maxcost(int s,int t)
{
int flow = 0 , cost = 0;
while (spfa(s,t,flow,cost));
return cost;
}

int main()
{
while (scanf("%d",&q)==1,q)
{
input();
printf("%d\n",Maxcost(0,366));
}
}
0 0
原创粉丝点击