POJ 3469 构图最小割+链表SAP
来源:互联网 发布:华为和星环大数据 编辑:程序博客网 时间:2024/05/20 07:20
题目大意:
有一台双核处理器的电脑,现有很多模块,每个模块放在不同的核中都有一个花销。若某两个模块不放在同一个核中执行,那么会产生额外的花销。
求出使得所有的模块都进入处理器中的总花销值最小。
首先可以明确的是,该题为二分图,模块放入两个核中。
如果没有惩罚。
那么该题就是赤裸裸的最小割(其实是贪心)。
源点S与Acpu中的点连边,容量为模块放在A核中的费用。
B核中的点与汇点连边,容量为模块放在B核中的花销。
做一次最大流,流出的值即为最小割。
现在考虑产生额外的花销。若u,v不放在一个集合中。则会产生额外的花销,在图中,用一条增广路来表示。
(由于没有在自己电脑上码畜,PPT不好用就不配图了)
做完增广路后的图中,(u,u')边,两个端点至少有一个满流。对于(v,v')边同理。
若两边同时在源点或汇点满流,则惩罚不存在。
所以,要有惩罚,必须一点源点边满流,另一点汇点边满流。
而且满流边一定是割边。割边是肯定保留的,也就是不需要改变状态。
要改变状态的就是那些还没有流满的边,这些边才会有可行流。
若可行流的值(源点与汇点的可行流)大于额外花销,使得额外花销边满流,代表直接惩罚。
若可行流的值等于额外花销,则使得可行流至少一条边流满,流满的边代表模块改变核。
若可行流的值小于额外花销,则使得可行流流流满,代表状态改变。
所以 我们可以在u与v'和v与u'直接连边,容量为惩罚值。
至此初步构图完成。
现在援引这里的文章
这是这篇文章中很好的一个中间结论,我们可以把这个结论放置于很多网络流的题目中,进行点的合并。
在这题中可以加一条,若两点合并不影响其他点,则可以合并= =... 算个伪结论吧.....
这题可以把拆开的点u,u'合并成u点。
以下SAP板子为HH神的板....
#include<iostream>#include<string>#include<cstdio>#include<cstdlib>#define MN 22222#define MM 999999#define INF 0x7FFFFFFF#define FF(i,a) for( int i=0;i<a;i++ )#define CC(a) memset( a,0,sizeof(a) )template<class T>inline void checkmin( T &a,T b ){ if( a>b||a==-1 ) a=b; } using namespace std;struct edge{ int pos,cap,next;}E[MM];int N,M,s,t,alloc;int head[MN],pre[MN],cur[MN],dis[MN],gap[MN];void addEdge( int u,int v,int c,int cc=0 ){ E[alloc].pos=v; E[alloc].cap=c; E[alloc].next=head[u]; head[u]=alloc++; E[alloc].pos=u; E[alloc].cap=cc; E[alloc].next=head[v]; head[v]=alloc++;}void setG(){ CC(E);alloc=0; memset(head,-1,sizeof(head)); s=0;t=N+1; int u,v,val; for( int i=1;i<=N;i++ ){ scanf("%d",&val); addEdge( s,i,val ); scanf("%d",&val); addEdge( i,t,val ); } FF( i,M ){ scanf( "%d%d%d",&u,&v,&val ); addEdge( u,v,val,val ); }}int sap(){ CC(dis),CC(gap); FF( i,t+1 ) cur[i]=head[i]; int u=pre[s]=s,maxflow=0,aug=-1; gap[0]=t+1; while( dis[s]<=t ){loop: for( int &i=cur[u];i!=-1;i=E[i].next ) { int v=E[i].pos; if( E[i].cap&&dis[u]==dis[v]+1 ) { pre[v]=u; checkmin( aug,E[i].cap ); u=v; if( v==t ) { maxflow+=aug; //printf( "%d\n",maxflow ); for( u=pre[u];v!=s;v=u,u=pre[u] ) E[cur[u]].cap-=aug,E[cur[u]^1].cap+=aug; aug=-1; } goto loop; } } int mind=t; for( int i=head[u];i!=-1;i=E[i].next ) { int v=E[i].pos; if( E[i].cap&&mind>dis[v] ) cur[u]=i,mind=dis[v]; } if( --gap[dis[u]]==0 ) break; gap[dis[u]=mind+1]++; u=pre[u]; } return maxflow;}int main(){ while( scanf("%d%d",&N,&M)!=EOF ) { setG(); printf( "%d\n",sap() ); } return 0;}
- POJ 3469 构图最小割+链表SAP
- POJ 2125 - Destroying The Graph 构图最小割
- poj 3469 最小割模板sap+gap+弧优化
- poj 3469 最大流-最小割 SAP算法模板
- poj 3469 Dual Core CPU(最小割 SAP)
- poj 3469 最小割
- poj 3469 最小割
- POJ 3469 最小割
- POJ 3469 最小割
- poj 3469 最小割
- POJ 3469 最小割
- poj 3469(最小割)
- POJ 3469 (最小割)
- poj 3469(最小割)
- poj 3469(最小割)
- 【最小割】【poj 3469】 Language
- 3469poj(最小割)
- HDOJ 3657 - Game 构图最小割
- hdu 1431 素数回文
- Windows 8 Update将新增33个国家
- 突然想起幻世录1
- scea--- 我希望三年内搞定
- tftp命令
- POJ 3469 构图最小割+链表SAP
- 学习JAVA一个多月了
- 影响用户体验的4个因素
- 用rsync实现windows与linux文件同步的方法
- Oracle行转列 简单示例
- Get Data from Database without definited Structure
- iphone开发的几个Apple官方中文教程地址
- c++ STL 容器基础(一)
- 识别图片中的文字成文本格式