PKU 3680 Intervals

http://acm.pku.edu.cn/JudgeOnline/problem?id=3680

题意:有N个开区间,每个开区间有一个权值,问从中取任意多区间使得总权值最大;

建图:先离散化线段,将线段转化成两点,得到所有的线段端点,然后排序,对排序的第i个到i+1个连一条边,费用为0,流量为Inf,然后题意给出的线段也同样的连在途中,费用就w,流量为1,然后给一个源点s,汇点t 分别连在node[0],node[cnt-1]上,流量均为k;

这样就控制了每个点在覆盖次数不超过k次。。。。

代码:

 

#include<iostream> #include<queue> using namespace std ; const int N = 100010,Inf = 0x7fffffff; struct E { int ax,bx,w; }Sem[210]; int n,k,Max,s,t,en,maxflow,indx[N],pre[N],road[N],cnt,node[N]; struct Node { int vdx,flow,cost,next; }Edge[N*10]; void add(int from,int to,int cost,int flow) { Edge[en].vdx = to ; Edge[en].flow= flow ; Edge[en].cost= cost ; Edge[en].next= indx[from] ; indx[from] = en++ ; Edge[en].vdx = from ; Edge[en].flow= 0 ; Edge[en].cost= - cost ; Edge[en].next= indx[to] ; indx[to] = en++ ; } bool spfa() { queue<int>q; int visit[N],d[N]; for(int i=0;i<=t+1;i++) d[i]=-Inf; memset(visit,0,sizeof(visit)); d[s]=0; visit[s]=1; q.push(s); while(!q.empty()) { int cur=q.front(); q.pop(); int next=indx[cur]; visit[cur]=0; while(next!=-1) { if(Edge[next].flow>0&&d[cur]+Edge[next].cost>d[Edge[next].vdx]) { d[Edge[next].vdx]=d[cur]+Edge[next].cost ; pre[Edge[next].vdx]=cur; road[Edge[next].vdx]=next; if(!visit[Edge[next].vdx]) { visit[Edge[next].vdx]=1; q.push(Edge[next].vdx); } } next=Edge[next].next; } } if(d[t]==-Inf) return false; return true ; } void argue() { int minflow=Inf; for(int v=t;v!=s;v=pre[v]) minflow = min(minflow,Edge[road[v]].flow); for(int v=t;v!=s;v=pre[v]) { maxflow += minflow*Edge[road[v]].cost; Edge[road[v]].flow -= minflow ; Edge[road[v]^1].flow +=minflow ; } } int main() { int T ; scanf("%d",&T); for(int h=0;h<T;h++) { scanf("%d%d",&n,&k); cnt=0; for(int i=0;i<n;i++) { scanf("%d%d%d",&Sem[i].ax,&Sem[i].bx,&Sem[i].w) ; node[cnt++] = Sem[i].ax ; node[cnt++] = Sem[i].bx ; if(Sem[i].ax>Sem[i].bx) { int tmp = Sem[i].ax; Sem[i].ax = Sem[i].bx ; Sem[i].bx = tmp ; } } memset(indx,-1,sizeof(indx)); sort(node,node+cnt); Max=node[cnt-1] ; s=0,t=Max+1,en=0; for(int i=0;i<cnt-1;i++) { if(node[i]==node[i+1]) continue ; add(node[i],node[i+1],0,Inf); } for(int i=0;i<n;i++) add(Sem[i].ax,Sem[i].bx,Sem[i].w,1); add(s,node[0],0,k); add(Max,t,0,k); maxflow=0; while(spfa()&&(k--)) argue(); printf("%d/n",maxflow); } return 0 ; }   

你可能感兴趣的:(PKU 3680 Intervals)