题意:求XY平面上最左边的点到最右边的点的最大流。

分析:数据量大,EK算法TLE,要用SAP算法。SAP算法用的是

http://www.cnblogs.com/kuangbin/archive/2012/09/29/2707955.html

的模板。

#include <cstdio>
#include <cstring>
const int MAXN=;//点数的最大值
const int MAXM=;//边数的最大值
const int INF=0x3fffffff; struct Node
{
int from,to,next;
int cap;
}edge[MAXM];
int tol;
int head[MAXN];
int dep[MAXN];
int gap[MAXN];//gap[x]=y :说明残留网络中dep[i]==x的个数为y int n;//n是总的点的个数,包括源点和汇点 void init()
{
tol=;
memset(head,-,sizeof(head));
} void addedge(int u,int v,int w)
{
edge[tol].from=u;
edge[tol].to=v;
edge[tol].cap=w;
edge[tol].next=head[u];
head[u]=tol++;
edge[tol].from=v;
edge[tol].to=u;
edge[tol].cap=w;
edge[tol].next=head[v];
head[v]=tol++;
}
void BFS(int start,int end)
{
memset(dep,-,sizeof(dep));
memset(gap,,sizeof(gap));
gap[]=;
int que[MAXN];
int front,rear;
front=rear=;
dep[end]=;
que[rear++]=end;
while(front!=rear)
{
int u=que[front++];
if(front==MAXN)front=;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].to;
if(dep[v]!=-)continue;
que[rear++]=v;
if(rear==MAXN)rear=;
dep[v]=dep[u]+;
++gap[dep[v]];
}
}
}
int SAP(int start,int end)
{
int res=;
BFS(start,end);
int cur[MAXN];
int S[MAXN];
int top=;
memcpy(cur,head,sizeof(head));
int u=start;
int i;
while(dep[start]<n)
{
if(u==end)
{
int temp=INF;
int inser;
for(i=;i<top;i++)
if(temp>edge[S[i]].cap)
{
temp=edge[S[i]].cap;
inser=i;
}
for(i=;i<top;i++)
{
edge[S[i]].cap-=temp;
edge[S[i]^].cap+=temp;
}
res+=temp;
top=inser;
u=edge[S[top]].from;
}
if(u!=end&&gap[dep[u]-]==)//出现断层,无增广路
break;
for(i=cur[u];i!=-;i=edge[i].next)
if(edge[i].cap!=&&dep[u]==dep[edge[i].to]+)
break;
if(i!=-)
{
cur[u]=i;
S[top++]=i;
u=edge[i].to;
}
else
{
int min=n;
for(i=head[u];i!=-;i=edge[i].next)
{
if(edge[i].cap==)continue;
if(min>dep[edge[i].to])
{
min=dep[edge[i].to];
cur[u]=i;
}
}
--gap[dep[u]];
dep[u]=min+;
++gap[dep[u]];
if(u!=start)u=edge[S[--top]].from;
}
}
return res;
}
int main()
{
int T,m;
int s,t,x1,x2;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
scanf("%d%d",&x1,&x2);
x2 = x1;
s = t = ;
for(int i = ;i <= n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x < x1)
{
s = i;
x1 = x;
}
else if(x > x2)
{
t = i;
x2 = x;
}
}
init();
for(int i = ;i < m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
printf("%d\n",SAP(s,t));
}
return ;
}

最新文章

  1. 学习笔记:HTML5 Canvas绘制简单图形
  2. win8/10 特技
  3. Redis学习笔记~实现消息队列比MSMQ更方便
  4. Python的平凡之路(16)
  5. [NOIP2013] 提高组 洛谷P1969 积木大赛
  6. 运动历史图(MHI)——Motion History Image
  7. WAF指纹探测及识别技术&lt;freebuf&gt;
  8. jQuery 树形结构
  9. Android 开发中关于layoutinflater
  10. linux动态库加载时搜索路径
  11. javascript模式——Command
  12. Django-Views模块详解
  13. karaf 控制台 常用linux指令(1)
  14. Astah 使用 流程图、类图、时序图
  15. 小学四则运算APP 第一个冲刺阶段 第四天
  16. android studio 3.0之后版本自定义文件名生成apk文件
  17. eclipse jdk版本设置
  18. centos安装man中文手册
  19. 编写shell脚本需要特别关注的注意点
  20. 独家揭秘,106岁的IBM靠什么完成了世纪大转型|钛度专访

热门文章

  1. webrtc学习资源
  2. JSP-Runoob:JSP 文件上传
  3. 自定义滚动条配合鼠标滚轮demo
  4. [Apple开发者帐户帮助]九、参考(1)证书类型
  5. JavaScript中什么是包装对象?
  6. python自动化测试学习笔记-5常用模块
  7. 深入Mysql字符集设置
  8. spring-framework-4.1.x源码阅读环境搭建(导入Eclipse)
  9. Spring的核心机制依赖注入
  10. html5——伸缩比例