POJ 3680 - intervals 一类分配任务,有重叠限制的模型..最大费用最大流..
2013-09-05 11:02
549 查看
题意:
给了N个开区间..每个区间有权值..限定不能任何一个点被K个区间覆盖..问满足条件的选择区间..使得权值之和最大为多少..
题解:
将所有的点存下来排个序..也就是离散化..那么一共2n个点..记为m,令s为超级源点..e为超级汇点..做边s->1->2->3...->m-1->m->e..每条边容量为K..费用为0...再对于N个区间,其起点往终点做边..容量为1..权值为其权值的相反数..然后跑最小费用最大流..答案就是最小费用的相反数...
这类问题...提供几个参考: 算法正确性证明 、 DC :: Home的分析 、 从多进程动态规划到费用流的转化
Program:
给了N个开区间..每个区间有权值..限定不能任何一个点被K个区间覆盖..问满足条件的选择区间..使得权值之和最大为多少..
题解:
将所有的点存下来排个序..也就是离散化..那么一共2n个点..记为m,令s为超级源点..e为超级汇点..做边s->1->2->3...->m-1->m->e..每条边容量为K..费用为0...再对于N个区间,其起点往终点做边..容量为1..权值为其权值的相反数..然后跑最小费用最大流..答案就是最小费用的相反数...
这类问题...提供几个参考: 算法正确性证明 、 DC :: Home的分析 、 从多进程动态规划到费用流的转化
Program:
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<math.h> #include<queue> #define MAXN 1005 #define MAXM 800005 #define oo 1000000007 #define ll long long using namespace std; struct MCMF { struct node { int x,y,c,v,next; }line[MAXM]; int Lnum,_next[MAXN],pre[MAXN],dis[MAXN],flow,cost; bool inqueue[MAXN]; void initial(int n) { Lnum=-1; for (int i=0;i<=n;i++) _next[i]=-1; } void addline(int x,int y,int c,int v) { line[++Lnum].next=_next[x],_next[x]=Lnum; line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c,line[Lnum].v=v; line[++Lnum].next=_next[y],_next[y]=Lnum; line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0,line[Lnum].v=-v; } bool SPFA(int s,int e) { int x,k,y; queue<int> Q; while (!Q.empty()) Q.pop(); memset(dis,0x7f,sizeof(dis)); memset(inqueue,false,sizeof(inqueue)); Q.push(s); dis[s]=0,pre[s]=-1; while (!Q.empty()) { x=Q.front(),Q.pop(),inqueue[x]=false; for (k=_next[x];k!=-1;k=line[k].next) if (line[k].c) { y=line[k].y; if (dis[y]>dis[x]+line[k].v) { dis[y]=dis[x]+line[k].v; pre[y]=k; if (!inqueue[y]) { inqueue[y]=true; Q.push(y); } } } } if (dis[e]>oo) return false; flow=oo,cost=0; for (k=pre[e];k!=-1;k=pre[line[k].x]) flow=min(flow,line[k].c),cost+=line[k].v; cost*=flow; for (k=pre[e];k!=-1;k=pre[line[k].x]) line[k].c-=flow,line[k^1].c+=flow; return true; } void MinCostMaxFlow(int s,int e,int &Aflow,int &Acost) { Aflow=0,Acost=0; while (SPFA(s,e)) { Aflow+=flow; Acost+=cost; } } }T; int L[205][3],X[505]; int Bearch(int key,int n) { int l=0,r=n+1,mid; while (r-l>1) { mid=l+r>>1; if (X[mid]<key) l=mid; else r=mid; } return r; } int main() { int C,N,M,K,i,x,y,s,e,Af,Ac; scanf("%d",&C); while (C--) { scanf("%d%d",&N,&K); M=0; for (i=1;i<=N;i++) scanf("%d%d%d",&L[i][0],&L[i][1],&L[i][2]),X[++M]=L[i][0],X[++M]=L[i][1]; sort(X+1,X+1+M); s=0,e=500,T.initial(e); T.addline(s,1,K,0),T.addline(M,e,K,0); for (i=1;i<M;i++) T.addline(i,i+1,K,0); for (i=1;i<=N;i++) { x=Bearch(L[i][0],M),y=Bearch(L[i][1],M); if (x>y) swap(x,y); T.addline(x,y,1,-L[i][2]); } T.MinCostMaxFlow(s,e,Af,Ac); printf("%d\n",-Ac); } return 0; }
相关文章推荐
- 2014湘潭全国邀请赛I题 Intervals /POJ 3680 / 在限制次数下取有权区间使权最大/小问题(费用流)
- 2014湘潭全国邀请赛I题 Intervals /POJ 3680 / 在限制次数下取有权区间使权最大/小问题(费用流)
- poj 3680 Intervals 【坐标区间离散化 + 最大费用最大流】
- poj 3680 Intervals 最大费用流
- POJ 3680 Intervals (最大费用最大流)
- POJ 3680 Intervals (拆点 || 离散) && 最大费用流
- poj 3680 Intervals(最大费用流+离散化)
- 网络流(最大费用最大流) :POJ 3680 Intervals
- poj 3680 Intervals(费用流)
- poj 3680(最大费用最大流)
- POJ-3680:Intervals (费用流)
- 【POJ】 3680 Intervals 离散 + 费用流
- poj 3680 Intervals(巧妙构图,费用流)
- POJ 3680 Intervals 费用流构图题(区间的一定考虑相邻的)
- [费用流] POJ 3680 Intervals
- poj 3680 Intervals 费用流
- POJ 3680 Intervals(费用流+负权优化)
- POJ - 3680 Intervals 区间图的最大权独立集(最大流)
- POJ 3680 Intervals (费用流经典构图题)
- POJ 3690 Intervals 费用流 最大变最小