poj 3680 Intervals
給定N個帶權(quán)的開區(qū)間,第i個區(qū)間覆蓋區(qū)間(ai,bi),權(quán)值為wi?,F(xiàn)在要求挑出一些區(qū)間使得總權(quán)值最大,并且滿足實(shí)軸上任意一個點(diǎn)被覆蓋不超過K次。
1<=K<=N<=200.1<=ai<bi<=100000.1<=wi<=100000.
最小費(fèi)用最大流。
將所有區(qū)間端點(diǎn)離散化到整數(shù)1到M,每個數(shù)對應(yīng)一個點(diǎn)。
源點(diǎn)向整數(shù)1點(diǎn)連一條容量為K費(fèi)用為0的邊。
整數(shù)i點(diǎn)向整數(shù)i+1點(diǎn)連一條容量為正無窮費(fèi)用為0的邊。(1<=i<M).
整數(shù)M點(diǎn)向匯點(diǎn)連一條容量為正無窮費(fèi)用為0的邊。
每個區(qū)間由aai點(diǎn)向bbi點(diǎn)連一條容量為1費(fèi)用為-wi的邊(aai和bbi為區(qū)間左右端點(diǎn)離散后的值)。
最小費(fèi)用最大流取反即為答案。
考慮對于一條aai向bbi的邊,費(fèi)用為負(fù)值必然優(yōu)先選擇,使得區(qū)間(aai,bbi)剩余流量減一,對應(yīng)題中(ai,bi)的點(diǎn)剩余覆蓋次數(shù)減一。注意到本題區(qū)間為開區(qū)間,所以兩個區(qū)間相連不影響結(jié)果。
1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<iostream> 5 #include<queue> 6 using namespace std; 7 const int dian=405; 8 const int bian=1505; 9 const int INF=0x3f3f3f3f; 10 int zkh[dian],ykh[dian],khqz[dian]; 11 int zl[dian],yl[dian]; 12 int h[dian],nxt[bian],ver[bian],val[bian],cos[bian],minn[dian],with[dian]; 13 int v[dian],d[dian]; 14 int n,k,tot,bula; 15 int S,T; 16 void add(int a,int b,int c,int d){ 17 tot++;ver[tot]=b;val[tot]=c;cos[tot]=d;nxt[tot]=h[a];h[a]=tot; 18 tot++;ver[tot]=a;val[tot]=0;cos[tot]=-d;nxt[tot]=h[b];h[b]=tot; 19 } 20 bool tell(){ 21 memset(v,0,sizeof(v)); 22 memset(d,0x3f,sizeof(d)); 23 memset(with,0,sizeof(with)); 24 memset(minn,0x3f,sizeof(minn)); 25 queue<int>q; 26 q.push(S); 27 v[S]=1; 28 d[S]=0; 29 while(!q.empty()){ 30 int x=q.front(); 31 q.pop(); 32 v[x]=0; 33 for(int i=h[x];i;i=nxt[i]){ 34 int y=ver[i]; 35 if(d[y]>d[x]+cos[i]&&val[i]){ 36 d[y]=d[x]+cos[i]; 37 minn[y]=min(minn[x],val[i]); 38 with[y]=i; 39 if(!v[y]){ 40 v[y]=1; 41 q.push(y); 42 } 43 } 44 } 45 } 46 if(d[T]==0x3f3f3f3f) 47 return 0; 48 return 1; 49 } 50 int zeng(){ 51 for(int i=T;i!=S;i=ver[with[i]^1]){ 52 val[with[i]]-=minn[T]; 53 val[with[i]^1]+=minn[T]; 54 } 55 return minn[T]*d[T]; 56 } 57 int dinic_cost(){ 58 int r=0; 59 while(tell()) 60 r+=zeng(); 61 return r; 62 } 63 int main(){ 64 int cas; 65 scanf("%d",&cas); 66 while(cas--){ 67 memset(h,0,sizeof(h)); 68 memset(nxt,0,sizeof(nxt)); 69 tot=1; 70 bula=0; 71 scanf("%d%d",&n,&k); 72 for(int i=1;i<=n;i++) 73 scanf("%d%d%d",&zkh[i],&ykh[i],&khqz[i]); 74 //本人太過蒟蒻,下文大段while語句(離散化)不知所云,建議跳過。 75 int hhd; 76 while(1){ 77 hhd=INF; 78 for(int i=1;i<=n;i++) 79 if(hhd>zkh[i]) 80 hhd=zkh[i]; 81 if(hhd==INF) 82 break; 83 bula++; 84 for(int i=1;i<=n;i++) 85 if(hhd==zkh[i]){ 86 if(ykh[i]==INF){ 87 zkh[i]=INF; 88 yl[i]=bula; 89 } 90 else{ 91 zkh[i]=ykh[i]; 92 ykh[i]=INF; 93 zl[i]=bula; 94 } 95 } 96 } 97 S=bula+1,T=bula+2; 98 for(int i=1;i<bula;i++) 99 add(i,i+1,INF,0); 100 add(S,1,k,0); 101 add(bula,T,INF,0); 102 for(int i=1;i<=n;i++) 103 add(zl[i],yl[i],1,-khqz[i]); 104 printf("%d\n",-dinic_cost()); 105 } 106 return 0; 107 }?
轉(zhuǎn)載于:https://www.cnblogs.com/dugudashen/p/6223955.html
總結(jié)
以上是生活随笔為你收集整理的poj 3680 Intervals的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CF722D. Generating S
- 下一篇: vue.js指令v-model实现方法