现在的位置: 首页 > 综合 > 正文

Intervals—-最小费用流

2013年09月05日 ⁄ 综合 ⁄ 共 1829字 ⁄ 字号 评论关闭

题目:http://poj.org/problem?id=3680

还是建图的问题。

离散化+最小费用流。

推荐博文:http://hi.baidu.com/juner_king/blog/item/a6b7cc822cba01dd9023d933.html

源代码:(用时:547ms)

#include <stdio.h>
#include <string.h>
#include <algorithm>

using namespace  std;

typedef int typef;
typedef int typec;
const int N = 405, M = 2000;
const typef inff = 0x3f3f3f3f;
const typec infc = 0x3f3f3f3f;

int a[N],b[N];

int l[N],r[N],w[N];

int x,n,k,cas;

struct MinCostMaxFlow {
	int e, ev[M], nxt[M], head[N];
	typec cost[M], dist[N];
	typef cap[M];
	int pnt[N], road[N], q[N], bg, ed;
	bool vis[N];

	void init() { e = 0; memset(head,-1,sizeof(head)); }

	void addedge(int u, int v, typef f, typec c) { //u->v flow=f, cost=c
		ev[e]=v; cap[e]=f; cost[e]=c; nxt[e]=head[u]; head[u]=e++;
		ev[e]=u; cap[e]=0; cost[e]=-c; nxt[e]=head[v]; head[v]=e++;
	}

	bool spfa(int s, int t, int n) {
		for(int i=0;i<=n;i++) dist[i] = infc, vis[i] = 0;
		bg = ed = dist[s] = 0;
		pnt[s] = s; q[ed++] = s;
		while (bg != ed) {
			int u = q[bg++]; vis[u] = 0;
			if (bg == N) bg = 0;
			for (int i = head[u]; ~i; i = nxt[i]) {
				if (cap[i] <= 0)continue;
				int v = ev[i];
				if (dist[v] > dist[u] + cost[i]) {
					dist[v] = dist[u] + cost[i];
					pnt[v] = u; road[v] = i;
					if (!vis[v]) {
						q[ed++] = v; vis[v] = 1;
						if(ed == N)ed = 0;
					}
				}
			}
		}
		return dist[t] != infc;
	}

	void mincost(int s, int t, int n, typef &f, typec &c) {
		c = f = 0;
		while(spfa(s, t, n)){
			typef minf = inff;
			for(int u = t; u != s; u = pnt[u])
				minf = min(minf, cap[road[u]]);
			for(int u = t; u != s; u = pnt[u]){
				cap[road[u]] -= minf;
				cap[road[u] ^ 1] += minf;
			}
			f += minf;
			c += minf * dist[t];
		}
	}
};


int solve()
{
    int xx,ll,rr;
    int ans1,ans;
    MinCostMaxFlow tmp;
    sort(a,a+x);  xx=0;  b[xx++]=a[0];
    for(int i=1;i<x;i++)
      if(a[i]!=a[i-1])
       b[xx++]=a[i];
    tmp.init();
    for(int i=1;i<=xx+1;i++)
     tmp.addedge(i-1,i,k,0);
   for(int i=1;i<=n;i++)
    {
        for(int j=0;j<xx;j++)
          {
              if(b[j]==l[i])
               ll=j+1;
              if(b[j]==r[i])
               rr=j+1;
          }
       tmp.addedge(ll,rr,1,-w[i]);
    }
    tmp.mincost(0,xx+1,xx+2,ans1,ans);
    return -ans;
}

int main()
{
    //freopen("F:\\a.txt","r",stdin);
    scanf("%d",&cas);
    while(cas--)
    {
        scanf("%d %d",&n,&k);
        x=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d %d %d",&l[i],&r[i],&w[i]);
            a[x++]=l[i];  a[x++]=r[i];
        }
        printf("%d\n",solve());
    }
}

抱歉!评论已关闭.