Intervals POJ - 3680

传送门

给定数轴上n个带权区间$[l_i,r_i]$,权值为$w_i$

选出一些区间使权值和最大,且每个点被覆盖次数不超过k次。

离散+拆点,最大费用可行流(跑到费用为负为止)

第一部分点按下标串起来,相邻两个点之间连容量为k,费用为0的边

拆的两个点之间连容量为k,费用为0的双向边

第二部分点按区间连容量为1,费用为w的边。

第一部分流向第二部分表示开始覆盖,第二部分流向第一部分表示结束覆盖,同一时间内正在覆盖的容量不会超过k。

  1 //Achen
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdlib>
  6 #include<vector>
  7 #include<cstdio>
  8 #include<queue>
  9 #include<cmath>
 10 #include<set>
 11 #include<map>
 12 #define Formylove return 0
 13 #define For(i,a,b) for(int i=(a);i<=(b);i++)
 14 #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
 15 const int M=4007,N=850;
 16 typedef long long LL;
 17 typedef double db;
 18 using namespace std;
 19 int n,k,ls[N],l[N],r[N],w[N];
 20 
 21 template<typename T>void read(T &x)  {
 22     char ch=getchar(); x=0; T f=1;
 23     while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
 24     if(ch=='-') f=-1,ch=getchar();
 25     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
 26 }
 27 
 28 struct edge {
 29     int u,v,cap,fl,cost,nx;
 30     edge(){}
 31     edge(int u,int v,int cap,int fl,int cost,int nx):u(u),v(v),cap(cap),fl(fl),cost(cost),nx(nx){} 
 32 }e[M];
 33 
 34 int ecnt=1,fir[N];
 35 void add(int u,int v,int cap,int cost) {
 36     e[++ecnt]=edge(u,v,cap,0,cost,fir[u]); fir[u]=ecnt;
 37     //printf("%d->%d:%d\n",u,v,cap);
 38     e[++ecnt]=edge(v,u,0,0,-cost,fir[v]); fir[v]=ecnt;
 39 }
 40 
 41 queue<int>que;
 42 int d[N],vis[N],p[N];
 43 int spfa(int s,int t) {
 44     For(i,1,n) d[i]=-1;
 45     d[s]=0; que.push(s); 
 46     while(!que.empty()) {
 47         int x=que.front();
 48         que.pop(); vis[x]=0;
 49         for(int i=fir[x];i;i=e[i].nx) if(e[i].cap>e[i].fl) {
 50             int y=e[i].v;
 51             if(d[y]<d[x]+e[i].cost) {
 52                 p[y]=i;
 53                 d[y]=d[x]+e[i].cost;
 54                 if(!vis[y]) {
 55                     vis[y]=1;
 56                     que.push(y); 
 57                 }
 58             }
 59         }
 60     }
 61     return d[t]>0;
 62 }
 63 
 64 #define inf 1e9
 65 int calc(int s,int t) {
 66     int fl=inf,cost=0;
 67     for(int i=t;i!=s;i=e[p[i]].u)
 68         fl=min(fl,e[p[i]].cap-e[p[i]].fl);
 69     for(int i=t;i!=s;i=e[p[i]].u) {
 70         e[p[i]].fl+=fl,e[p[i]^1].fl-=fl;
 71         cost+=e[p[i]].cost; 
 72     }
 73     return fl*cost;
 74 }
 75 
 76 int EK(int s,int t) {
 77     int rs=0;
 78     while(spfa(s,t)) {
 79         rs+=calc(s,t);
 80     }
 81     return rs;
 82 } 
 83 
 84 void init() {
 85     ecnt=1;
 86     memset(fir,0,sizeof(fir)); 
 87 }
 88 
 89 int main() {
 90 #ifdef ANS
 91     freopen(".in","r",stdin);
 92     freopen(".out","w",stdout);
 93 #endif
 94     int T; read(T);
 95     while(T--) {
 96         init();
 97         read(n); read(k);
 98         ls[0]=0;
 99         For(i,1,n) {
100             read(l[i]); read(r[i]); read(w[i]);
101             ls[++ls[0]]=l[i];
102             ls[++ls[0]]=r[i];
103         }
104         sort(ls+1,ls+ls[0]+1);
105         int sz=unique(ls+1,ls+ls[0]+1)-(ls+1);
106         int s=sz*2+1,t=s+1;
107         add(s,1,k,0);
108         For(i,1,sz-1) add(i,i+1,k,0);
109         add(sz,t,k,0);
110         For(i,1,sz) add(i,sz+i,k,0),add(sz+i,i,k,0);
111         For(i,1,n) {
112             int a=l[i],b=r[i];
113             a=lower_bound(ls+1,ls+sz+1,a)-ls;
114             b=lower_bound(ls+1,ls+sz+1,b)-ls;
115             add(sz+a,sz+b,1,w[i]);
116         }
117         n=t;
118         int ans=EK(s,t);
119         printf("%d\n",ans);
120     }
121     Formylove;
122 }
123 /*
124 4
125 
126 3 1
127 1 2 2
128 2 3 4
129 3 4 8
130 
131 3 1
132 1 3 2
133 2 3 4
134 3 4 8
135 
136 3 1
137 1 100000 100000
138 1 2 3
139 100 200 300
140 
141 3 2
142 1 100000 100000
143 1 150 301
144 100 200 300
145 */
View Code

 

posted @ 2018-08-27 20:40  啊宸  阅读(206)  评论(0编辑  收藏  举报