POJ 3680 最大费用流
题意:
有N个整数区间,每个区间有一个权值,从中取一些区间,使得任意整数点的重叠数不大于K,并且这些区间的总权值最大。
ps:区间不能重复选择!
题解:
经典的建图,表示自己想了好多都没有想到,最后还是lyd给我讲的。。。
先离散化,建立边(i,i+1,k,0),i到i+1容量k费用0的边;边(i,j,1,w),i和j为给定区间的左右端点,容量1费用0,最大费用流即可~
View Code
1 #include <iostream>
2 #include <algorithm>
3 #include <cstdlib>
4 #include <cstdio>
5 #include <cstring>
6
7 #define M 10000
8 #define N 800
9 #define INF 1E9
10
11 using namespace std;
12
13 int to[M],next[M],head[N],len[M],pr[M],val[N],pre[N],q[M],dis[N],son[N];
14 bool vis[N];
15 int S,T,bcnt,cnt,tot,n,k,cas;
16
17 struct PX
18 {
19 int b,w,tb,bh;
20 }px[N];
21
22 inline bool cmp(const PX &a,const PX &b)
23 {
24 return a.b<b.b;
25 }
26
27 inline bool cmpbh(const PX &a,const PX &b)
28 {
29 if(a.bh==b.bh) return a.tb<b.tb;
30 return a.bh<b.bh;
31 }
32
33 inline void add(int u,int v,int r,int w)
34 {
35 to[tot]=v; len[tot]=r; pr[tot]=w; next[tot]=head[u]; head[u]=tot++;
36 to[tot]=u; len[tot]=0; pr[tot]=-w; next[tot]=head[v]; head[v]=tot++;
37 }
38
39 inline void read()
40 {
41 memset(head,-1,sizeof head); tot=0;
42 scanf("%d%d",&n,&k);
43 cnt=0;
44 for(int i=1,a,b;i<=n;i++)
45 {
46 scanf("%d%d%d",&a,&b,&val[i]);
47 cnt++; px[cnt].b=a; px[cnt].bh=i;
48 cnt++; px[cnt].b=b; px[cnt].bh=i;
49 }
50 sort(px+1,px+1+cnt,cmp);
51 bcnt=0;
52 for(int i=1;i<=cnt;i++)
53 {
54 if(px[i].b!=px[i-1].b) px[i].tb=++bcnt;
55 else px[i].tb=bcnt;
56 }
57 sort(px+1,px+1+cnt,cmpbh);
58 }
59
60 inline bool spfa()
61 {
62 for(int i=0;i<=T;i++) dis[i]=-INF;
63 memset(pre,-1,sizeof pre);
64 int h=1,t=2,sta;
65 q[1]=S; vis[S]=true; dis[S]=0;
66 while(h<t)
67 {
68 sta=q[h++]; vis[sta]=false;
69 for(int i=head[sta];~i;i=next[i])
70 if(len[i]>0&&dis[to[i]]<dis[sta]+pr[i])
71 {
72 dis[to[i]]=dis[sta]+pr[i];
73 pre[to[i]]=i;
74 if(!vis[to[i]]) vis[to[i]]=true,q[t++]=to[i];
75 }
76 }
77 return pre[T]!=-1;
78 }
79
80 inline void updata()
81 {
82 for(int i=pre[T];~i;i=pre[to[i^1]])
83 {
84 len[i]-=1; len[i^1]+=1;
85 }
86 }
87
88 inline void go()
89 {
90 S=0; T=bcnt+1;
91 for(int i=0;i<=bcnt;i++) add(i,i+1,k,0);
92 for(int i=1;i<=cnt;i+=2) add(px[i].tb,px[i+1].tb,1,val[px[i].bh]);
93 int ans=0;
94 while(spfa()) ans+=dis[T],updata();
95 printf("%d\n",ans);
96 }
97
98 int main()
99 {
100 scanf("%d",&cas);
101 while(cas--) read(),go();
102 return 0;
103 }
没有人能阻止我前进的步伐,除了我自己!

View Code
浙公网安备 33010602011771号