poj 3680(最小费用流)
来源:互联网 发布:在墨尔本生活知乎 编辑:程序博客网 时间:2024/06/05 15:11
传送门
问题:数轴上有若干个带权值的闭区间(刘汝佳蓝书P367写的是左闭右开区间,个人根据样例数据和解法推测应该是笔误),选出一些区间使权值和尽量大且任意一个数均被覆盖k次
题解:经典的最小费用流模型,连边方法写在代码开头,具体为什么要这样连边本蒟蒻也不易表述清楚,但是在纸上模拟几组数据发现确实是对的,应该还是很好理解的,实在理解不了的—>戳这儿
注意:区间最好先离散化,最后答案是费用的相反数
/* for every interval, adde(u,v,1,w); for i=1~(tot-1), adde(i,i+1,INF,0); adde(0,1,k,0), adde(tot,tot+1,k,0)*/#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<map>#include<queue>using namespace std;const int maxn=101000;const int INF=0x3f3f3f3f;int n,k;int head[maxn],edge,source,sink;struct EDGE { int u,v,nxt,r,c;}e[maxn];int dis[maxn],pre[maxn];bool inq[maxn];int a[maxn],b[maxn],c[maxn],f[maxn<<1],tot;int mp[maxn];inline void adde(int u,int v,int r,int c) { e[edge].u=u,e[edge].v=v,e[edge].nxt=head[u],e[edge].r=r,e[edge].c=c,head[u]=edge++; e[edge].u=v,e[edge].v=u,e[edge].nxt=head[v],e[edge].r=0,e[edge].c=-c,head[v]=edge++;}inline bool spfa() { queue<int> q; memset(inq,false,sizeof(inq)); memset(dis,INF,sizeof(dis)); dis[source]=0,q.push(source),inq[source]=true,pre[source]=-1; while (!q.empty()) { int p=q.front(); q.pop(),inq[p]=false; for (int i=head[p];~i;i=e[i].nxt) { int v=e[i].v; if (e[i].r>0&&dis[v]>dis[p]+e[i].c) { pre[v]=i, dis[v]=dis[p]+e[i].c; if (!inq[v]) { inq[v]=true; q.push(v); } } } } return dis[sink]^INF;}inline int MCMF() { int ans=0; while (spfa()) { int tmp=INF; for (int i=pre[sink];~i;i=pre[e[i].u]) tmp=min(tmp,e[i].r); ans+=tmp*dis[sink]; for (int i=pre[sink];~i;i=pre[e[i].u]) e[i].r-=tmp,e[i^1].r+=tmp; } return -ans;}inline int read() { int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); return x*f;}int main() {// freopen("poj 3680.in","r",stdin); int kase=read(); while (kase--) { memset(head,-1,sizeof(head)); edge=0; f[0]=0,tot=0; n=read(),k=read(); for (int i=1;i<=n;++i) { a[i]=read(),b[i]=read(),c[i]=read(); f[(i<<1)-1]=a[i],f[i<<1]=b[i]; } sort(f+1,f+(n<<1)+1); int nn=n<<1; for (int i=1;i<=nn;++i) if (f[i]!=f[i-1]) mp[f[i]]=++tot;//discretize intervals for (int i=1;i<tot;++i) adde(i,i+1,INF,0); source=0,sink=tot+1; adde(source,1,k,0),adde(tot,sink,k,0); for (int i=1;i<=n;++i) adde(mp[a[i]],mp[b[i]],1,-c[i]); printf("%d\n",MCMF()); } return 0;}
阅读全文
0 0
- POJ 3680 Intervals(最小费用流)
- POJ 3680 Intervals(最小费用流)
- poj 3680(最小费用流)
- poj 3680 最小费用流
- 【最小费用流】POJ
- Intervals (poj 3680 离散化+最小费用最大流)
- poj/pku 3680(最小费用最大流)
- POJ 3680 最小费用最大流
- poj 3680(最小费用最大流)
- POJ 3680 最小费用最大流
- poj 3680 Intervals (最小费用最大流)
- POJ 3680 最小费用最大流
- POJ 3680 最小费用最大流
- Intervals poj 3680 最小费用最大流
- poj 2159(最小费用最大流)
- POJ 2516(最小费用最大流)
- poj 2195 (最小费用最大流)
- Poj 3422(最小费用流)
- 自定义view继承RelativeLayout
- 反素数
- shiro进阶—与javaweb整合
- 性能与可靠性要求说明书-模板
- 大数欧拉
- poj 3680(最小费用流)
- IDL中数据导出为栅格文件的方式
- 九九乘法表
- D
- MongoDB Java API for 插入和单collection基本查询使用示例
- HTML5 <datalist>标签
- 前端跨域
- JavaScript的全局函数
- Python 基础 —— Twisted介绍