标签:
2016-06-01 22:01:39
题目链接: POJ No.3680 Intervals
题目大意:
给定N个带权区间,最多可以重复选一个点M次,求出一种选法使得所得权最大
解法:
费用流
建模:
区间的端点之间按照副权流量1连接,而每个点之间需要再连0权流量无穷作为跳过用
注意的地方:
十万个点肯定是不行的,看我unique离散化大法
1 //Intervals (POJ No.3680) 2 //费用流 3 #include<stdio.h> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 const int maxn=410; 8 int T,N,K; 9 int hash[maxn]; 10 int a[maxn]; 11 int w[maxn]; 12 struct edge 13 { 14 int to; 15 int from; 16 int cost; 17 int flow; 18 int next; 19 edge(){} 20 edge(int from,int to,int cost,int flow,int next):from(from),to(to),cost(cost),flow(flow),next(next){} 21 }; 22 edge n[maxn*10]; 23 int cnt; 24 int len; 25 int now; 26 int head[maxn]; 27 bool vis[maxn]; 28 int dist[maxn]; 29 int pre[maxn]; 30 queue <int> q; 31 void insert(int x,int y,int z,int cost) 32 { 33 n[++cnt]=edge(x,y,cost,z,head[x]); 34 head[x]=cnt; 35 n[++cnt]=edge(y,x,-cost,0,head[y]); 36 head[y]=cnt; 37 return ; 38 } 39 void SPFA(int s,int t) 40 { 41 fill(dist,dist+maxn,100000); 42 q.push(s); 43 vis[s]=1; 44 dist[s]=0; 45 while(!q.empty()) 46 { 47 now=q.front(); 48 q.pop(); 49 vis[now]=0; 50 for(int i=head[now];i;i=n[i].next) 51 { 52 if(n[i].flow>0) 53 { 54 if(dist[n[i].to]>dist[now]+n[i].cost) 55 { 56 dist[n[i].to]=dist[now]+n[i].cost; 57 pre[n[i].to]=i; 58 if(!vis[n[i].to]) 59 { 60 vis[n[i].to]=1; 61 q.push(n[i].to); 62 } 63 } 64 } 65 } 66 } 67 for(int i=pre[t];i;i=pre[n[i].from]) 68 { 69 n[i].flow--; 70 n[i^1].flow++; 71 } 72 return ; 73 } 74 int Mincost_flow(int s,int t,int num) 75 { 76 int ans=0; 77 while(num--) 78 { 79 SPFA(s,t); 80 ans+=dist[t]; 81 } 82 return -ans; 83 } 84 int main() 85 { 86 scanf("%d",&T); 87 while(T--) 88 { 89 cnt=1; 90 fill(head,head+maxn,0); 91 scanf("%d %d",&N,&K); 92 for(int i=1;i<=N;i++) 93 { 94 scanf("%d %d",&a[i*2-1],&a[i*2]); 95 scanf("%d",&w[i]); 96 hash[i*2-1]=a[i*2-1]; 97 hash[i*2]=a[i*2]; 98 } 99 sort(hash+1,hash+2*N+1); 100 len=unique(hash+1,hash+2*N+1)-hash-1; 101 for(int i=1;i<=N*2;i++) 102 { 103 a[i]=lower_bound(hash+1,hash+len+1,a[i])-hash; 104 if(!(i&1))insert(a[i-1],a[i],1,-w[i/2]); 105 } 106 for(int i=1;i<len;i++)insert(i,i+1,100000,0); 107 insert(len,len+1,K,0); 108 insert(0,1,K,0); 109 printf("%d\n",Mincost_flow(0,len+1,K)); 110 } 111 }
标签:
原文地址:http://www.cnblogs.com/Neptune-/p/5551267.html