您的位置:首页 > 理论基础 > 计算机网络

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

2014-02-08 09:55 459 查看
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

i

j

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 

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 7273
22 139 7851
194 198 9190
119 274 878
122 173 8640
0


Sample
Output 

30
25500
38595

题意:你有个两个能举行音乐会的房间。你要在一年内以出租的方式经营这两件房间,你会接到一些单子,单子内容包括租用的时间段以及价钱,接单子的时候不能有时间上的冲突。你要尽可能盈利,不管他的音乐会的质量→_→ 
思路:这个题目如果只有一个房间,那么之间用最长路就行了,但是有两个房间,我们能用网络流,想象一下图中有两个流从第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)); }}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: