标签:
引用下题解:
lyd:
首先把区间端点离散化,设原来的数值i离散化后的标号是c[i]。这样离散化之后,整个数轴被分成了一段段小区间。
1.建立S和T,从S到离散化后的第一个点连容量K,费用0的边。离散化后的最后一个点到T连容量K、费用0的边。
2.离散化后的相邻点之间(从i到i+1)连容量为K,费用为0的边。
3.输入的区间从离散化后的左端点到右端点连容量1、费用W的边。
感觉好神啊……
其实应该只要把源点到第一个点的流量限制为k应该就可以了……这个构思蛮巧妙的……限制了每个地方最多有k个流出去。
另外,这题是最大费用最大流,所以按上面的建图方式需要改一下预处理和增广的条件,或者就是建图的时候所有的费用取负,再将最后答案取负。
1 Source Code 2 Problem: 3680 User: sdfzyhy 3 Memory: 752K Time: 563MS 4 Language: G++ Result: Accepted 5 6 Source Code 7 8 //BZOJ 3680 9 #include<cmath> 10 #include<vector> 11 #include<cstdio> 12 #include<cstring> 13 #include<cstdlib> 14 #include<iostream> 15 #include<algorithm> 16 #define rep(i,n) for(int i=0;i<n;++i) 17 #define F(i,j,n) for(int i=j;i<=n;++i) 18 #define D(i,j,n) for(int i=j;i>=n;--i) 19 #define pb push_back 20 #define CC(a,b) memset(a,b,sizeof(a)) 21 using namespace std; 22 int getint(){ 23 int v=0,sign=1; char ch=getchar(); 24 while(!isdigit(ch)) {if(ch==‘-‘) sign=-1; ch=getchar();} 25 while(isdigit(ch)) {v=v*10+ch-‘0‘; ch=getchar();} 26 return v*sign; 27 } 28 const int N=510,M=100000,INF=~0u>>2; 29 const double eps=1e-8; 30 /*******************template********************/ 31 int n,m,k,ans,a[N],b[N],c[N],w[N]; 32 struct edge{int from,to,v,c;}; 33 struct Net{ 34 edge E[M]; 35 int head[N],next[M],cnt; 36 void ins(int x,int y,int z,int c){ 37 E[++cnt]=(edge){x,y,z,c}; 38 next[cnt]=head[x]; head[x]=cnt; 39 } 40 void add(int x,int y,int z,int c){ 41 ins(x,y,z,c); ins(y,x,0,-c); 42 } 43 int S,T,d[N],Q[M],from[N]; 44 bool inq[N]; 45 bool spfa(){ 46 int l=0,r=-1; 47 F(i,S,T) d[i]=INF; 48 d[S]=0; Q[++r]=S; inq[S]=1; 49 while(l<=r){ 50 int x=Q[l++]; inq[x]=0; 51 for(int i=head[x];i;i=next[i]) 52 if(E[i].v && d[x]+E[i].c<d[E[i].to]){ 53 d[E[i].to]=d[x]+E[i].c; 54 from[E[i].to]=i; 55 if (!inq[E[i].to]){ 56 Q[++r]=E[i].to; 57 inq[E[i].to]=1; 58 } 59 } 60 } 61 return d[T]!=INF; 62 } 63 void mcf(){ 64 int x=INF; 65 for(int i=from[T];i;i=from[E[i].from]) 66 x=min(x,E[i].v); 67 for(int i=from[T];i;i=from[E[i].from]){ 68 E[i].v-=x; 69 E[i^1].v+=x; 70 } 71 ans+=x*d[T]; 72 } 73 void init(){ 74 n=getint(); k=getint(); 75 cnt=1; ans=0; 76 memset(head,0,sizeof head); 77 int x,y; 78 F(i,1,n){ 79 a[i]=c[(i<<1)-1]=getint(); 80 b[i]=c[i<<1]=getint(); 81 w[i]=getint(); 82 } 83 sort(c+1,c+n*2+1); 84 int num=unique(c+1,c+n*2+1)-c-1; 85 S=0; T=num+1; 86 F(i,0,num) add(i,i+1,k,0); 87 F(i,1,n){ 88 a[i]=lower_bound(c+1,c+num+1,a[i])-c; 89 b[i]=lower_bound(c+1,c+num+1,b[i])-c; 90 add(a[i],b[i],1,-w[i]); 91 } 92 while(spfa()) mcf(); 93 printf("%d\n",-ans); 94 } 95 }G1; 96 int main(){ 97 #ifndef ONLINE_JUDGE 98 freopen("input.txt","r",stdin); 99 // freopen("output.txt","w",stdout); 100 #endif 101 int T=getint(); 102 while(T--) G1.init(); 103 return 0; 104 }
标签:
原文地址:http://www.cnblogs.com/Tunix/p/4349410.html