Hubtown(最大流)
Hubtown
时间限制: 1 Sec 内存限制: 128 MB
提交: 23 解决: 11
[提交] [状态] [讨论版] [命题人:admin]
题目描述
A citizen will always take the train line which is of least angular distance from its house. However, if a citizen is exactly in the middle between two train lines, they are willing to take either of them, and city council can decide which of the two train lines the citizen should use.
See Figure H.1 for an example.
Figure H.1: Illustration of Sample Input 1. The dashed arrows indicate which train lines the citizens are closest to (note that we are measuring angular distances, not Euclidean distance).
Your task is to help the council, by finding a maximum size subset of citizens who can go by train in the morning to the central hub, ensuring that each of the citizens take one of the lines they are closest to, while not exceeding the capacity of any train line. For this subset, you should also print what train they are to take.
输入
The next n lines each contain two integers x and y, the Cartesian coordinates of a citizen’s home. No citizen lives at the central hub of the city.
Then follow m lines, each containing three integers x, y, and c describing a train line, where (x, y) are the coordinates of a single point (distinct from the central hub of the city) which the train line passes through and 0 ≤ c ≤ n is the capacity of the train line. The train line is the ray starting at (0, 0) and passing through (x, y).
All coordinates x and y (both citizens’ homes and the points defining the train lines) are bounded by 1000 in absolute value. No two train lines overlap, but multiple citizens may live at the same coordinates.
输出
样例输入
3 2
2 0
-1 0
-2 -1
1 -1 1
1 1 2
样例输出
3
0 1
1 1
2 0
思路:极角排序,建边求最大流!
AC代码;
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
const ld epsss=1e-;
const int N=4e5+,M=2e6+,inf=0x3f3f3f3f;
int n,m;
int ST,ED,ID;
int first[N],w[M],cap[M],nxt[M];
void ins(int x,int y,int cap_)
{
w[++ID]=y;
cap[ID]=cap_;
nxt[ID]=first[x];
first[x]=ID;
w[++ID]=x;
cap[ID]=;
nxt[ID]=first[y];
first[y]=ID;
}
int d[N];
bool bfs()
{
memset(d,-,sizeof(d));
d[ST]=;
queue<int>q;
q.push(ST);
while(!q.empty())
{
int x=q.front();
q.pop();
for(int z=first[x];z;z=nxt[z])
if(cap[z])
{
int y=w[z];
if(d[y]==-)
{
d[y]=d[x]+;
if(y==ED) return ;
q.push(y);
}
}
}
return ;
}
int dfs(int x,int all)
{
if(x==ED) return all;
int use=;
for(int z=first[x];z;z=nxt[z])
if(cap[z])
{
int y=w[z];
if(d[y]==d[x]+)
{
int tmp=dfs(y,min(cap[z],all-use));
cap[z]-=tmp;
cap[z^]+=tmp;
use+=tmp;
if(use==all) break;
}
}
if(use==) d[x]=-;
return use;
}
int dinic()
{
int tmp=;
while(bfs())
tmp+=dfs(ST,inf);
return tmp;
}
struct A
{
int x,y,o;
} a[N];
struct B
{
int x,y,o,c;
} b[N];
struct E
{
int x,y,t;
int sgn;
E() {}
E(int _x,int _y,int _t)
{
x=_x,y=_y,t=_t;
if(!x) sgn=y>;
else sgn=x>;
}
} e[];
bool cmpe(const E&a,const E&b)
{
if(a.sgn!=b.sgn) return a.sgn<b.sgn;
int t=a.x*b.y-a.y*b.x;
if(t) return t<;
return a.t<b.t;
}
int pre[],suf[];
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
bool point_on_line(const A&a,const B&b)
{
int d1=gcd(abs(a.x),abs(a.y)),d2=gcd(abs(b.x),abs(b.y));
return (a.x/d1==b.x/d2)&&(a.y/d1==b.y/d2);
}
struct Point
{
ll x,y;
Point() {}
Point(ll _x,ll _y)
{
x=_x,y=_y;
}
};
ll cross(const Point &a,const Point &b)
{
return a.x*b.y-a.y*b.x;
}
ll sig(ll x)
{
if(x==) return ;
return x>?:-;
}
struct Pointd
{
ld x,y;
Pointd() {}
Pointd(ld _x,ld _y)
{
x=_x,y=_y;
}
};
ld crossd(const Pointd&a,const Pointd&b)
{
return a.x*b.y-a.y*b.x;
}
ll sigd(ld x)
{
if(fabs(x)<epsss) return ;
return x>?:-;
}
int distance_cmp(const A&_a,const B&_b,const B&_c)
{
Point a(_a.x,_a.y);
Point b(_b.x,_b.y);
Point c(_c.x,_c.y);
Point d;
if(!cross(b,c))
{
d=Point(-b.y,b.x);
if(!cross(a,d))
return ;
if(sig(cross(d,a))==sig(cross(d,b)))
return -;
return ;
}
ld L=sqrt(b.x*b.x+b.y*b.y);
ld R=sqrt(c.x*c.x+c.y*c.y);
Pointd aa(a.x,a.y);
Pointd bb(b.x,b.y);
Pointd cc(c.x,c.y);
bb.x*=R;
bb.y*=R;
cc.x*=L;
cc.y*=L;
Pointd dd=Pointd(bb.x+cc.x,bb.y+cc.y);
if(!sigd(crossd(aa,dd)))
return ;
if(sigd(crossd(dd,aa))==sigd(crossd(dd,bb)))
return -;
return ;
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
ST=;
ED=n+m+;
ID=;
memset(first,,sizeof(first));
for(int i=;i<=n;++i)
{
scanf("%d %d",&a[i].x,&a[i].y);
a[i].o=i;
}
for(int i=;i<=m;++i)
{
scanf("%d %d %d",&b[i].x,&b[i].y,&b[i].c);
b[i].o=i;
}
int ce=;
for(int i=; i<=n; i++)
{
e[++ce]=E(a[i].x,a[i].y,i);
}
for(int i=; i<=m; i++)
{
e[++ce]=E(b[i].x,b[i].y,-i);
}
sort(e+,e+ce+,cmpe);
pre[]=;
for(int i=; i<=ce; i++)
if(e[i].t<)
pre[]=-e[i].t;
for(int i=; i<=ce; i++)
{
pre[i]=pre[i-];
if(e[i].t<)
pre[i]=-e[i].t;
}
suf[ce+]=;
for(int i=ce; i; i--)
if(e[i].t<)
suf[ce+]=-e[i].t;
for(int i=ce; i; i--)
{
suf[i]=suf[i+];
if(e[i].t<)
suf[i]=-e[i].t;
}
for(int i=; i<=ce; i++)
if(e[i].t>)
{
int x=e[i].t;
int L=pre[i],R=suf[i];
if(L==R)
{
ins(x,L+n,);
continue;
}
if(point_on_line(a[x],b[L]))
{
ins(x,L+n,);
continue;
}
if(point_on_line(a[x],b[R]))
{
ins(x,R+n,);
continue;
}
int t=distance_cmp(a[x],b[L],b[R]);
if(t<=)
ins(x,L+n,);
if(t>=)
ins(x,R+n,);
}
for(int i=;i<=n;++i)
{
ins(ST,i,);
}
for(int i=;i<=m;++i)
{
ins(n+i,ED,b[i].c);
}
printf("%d\n",dinic());
for(int i=;i<=n;++i)
{
for(int z=first[i];z;z=nxt[z])
{
int y=w[z];
if(y>n && cap[z]==)
{
printf("%d %d\n",i-,y-n-);
}
}
}
}
return ;
}
Hubtown(最大流)的更多相关文章
- Hubtown
Hubtown 时间限制: 10 Sec 内存限制: 256 MB 题目描述 Hubtown is a large Nordic city which is home to n citizens. ...
- 使用C#处理基于比特流的数据
使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...
- HTML 事件(三) 事件流与事件委托
本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...
- FILE文件流的中fopen、fread、fseek、fclose的使用
FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...
- java.IO输入输出流:过滤流:buffer流和data流
java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...
- java 字节流与字符流的区别
字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...
- BZOJ 3504: [Cqoi2014]危桥 [最大流]
3504: [Cqoi2014]危桥 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1407 Solved: 703[Submit][Status] ...
- java I/O流
输入流(读取数据的流) BufferedInputStream---继承--->FileInputStream--继承--->InputStream------> (1)字节流操作中 ...
- Ford-Fulkerson 最大流算法
流网络(Flow Networks)指的是一个有向图 G = (V, E),其中每条边 (u, v) ∈ E 均有一非负容量 c(u, v) ≥ 0.如果 (u, v) ∉ E 则可以规定 c(u, ...
随机推荐
- 使用 Fetch完成AJAX请求
使用 Fetch完成AJAX请求 写在前面 无论用JavaScript发送或获取信息,我们都会用到Ajax.Ajax不需要刷新页面就能发送和获取信息,能使网页实现异步更新. 几年前,初始化Ajax一般 ...
- goodBye wordPress
2016-07-28,我自己在GoDaddy上面注册了一个自己的域名,www.codetree.tech,同时在老薛主机上面购买了一个主机域名.我搭建了一个属于自己的博客,开心了很久.最近收到了域名续 ...
- GO WEB
1.第一个坑的就是,错误信息如下: 比较常见的错误“Connection reset by peer”,该错误和“Connection reset”是有区别的: 服务器返回了“RST”时,如果此时客户 ...
- C# 判断字符串为空(长度为0),或者是null(没有new)
string str = null; if (string.IsNullOrWhiteSpace(str)) { MessageBox.Show("字符串为null"); } ) ...
- MySQL · 引擎特性 · InnoDB index lock前世今生
http://mysql.taobao.org/monthly/2015/07/05/ MySQL · 引擎特性 · InnoDB index lock前世今生 前言 InnoDB并发过程中使用两类锁 ...
- (转)shell脚本输出带颜色字体
shell脚本输出带颜色字体 原文:http://blog.csdn.net/andylauren/article/details/60873400 输出特效格式控制:\033[0m 关闭所有属性 ...
- LeetCode 110.平衡二叉树(C++)
给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1. 示例 1: 给定二叉树 [3,9,20,null,nu ...
- malloc(0)分配多少内存?(译文)
原文地址:http://prog21.dadgum.com/179.html 在大多的系统中,这个C的小程序将会吸收全部空闲的内存. ){ ); } 在我们聊malloc(0)之前,让我们看看mall ...
- sqlldr 采集中文数据乱码问题
测试机上装入数据 发现中文字段全部变成???????,初步判断为字符集问题 更改 UPDATE sys.props$ SET VALUE$='WE8ISO8859P1' ...
- maven课程 项目管理利器-maven 3-3 maven中的坐标和仓库
本节主要讲了两大方面: 1 maven坐标 1.0 构件定义 任何依赖,插件,项目构建输出 都称之为构件. 1.1 maven坐标概念 groupid 公司或组织的域名倒序+当前项目名称 artif ...