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, ...
随机推荐
- 安装pyautogui时报错备注
python3.6用pip安装pyautogui时报错,找了蛮多方法都不行,最后通过安装低版本的pyautogui解决,这里备注下 报错图 解决方法: pip install pyautogui==0 ...
- spring boot——关于一个Mysql主键的问题
问题是这样的: 我现在有一个被@Entity标记的类TimeLine,其中id为主键. TimeLineController中有一个接收post请求的add()方法,这个方法会接受客户端传来的一个表单 ...
- 《mac的git安装手册-2》
<mac的git安装手册-2> 下载地址 https://git-scm.com/downloads 如果遇到打不开的情况,请在系统偏好设置内——>安全性与隐私下 ——>选择仍 ...
- app内部H5测试点总结
1.业务逻辑 除基本功能测试外,需要关注的一些测试点: a.登录 a.1 H5页面嵌入到客户端使用,若客户端已经登录,进入H5页面应该是登录状态 a.2 H5页面嵌入到客户端内使用,若客户端未登录,如 ...
- (转)Shell脚本之break,continue,和exit区别
Linux脚本中的break continue exit return break结束并退出循环 continue在循环中不执行continue下面的代码,转而进入下一轮循环 exit退出脚本,常带一 ...
- Kudu安装前的建议说明(博主推荐)
不多说,直接上干货! 能点击进来看我写的这篇博文的朋友,肯定是刚入门的你. 其实以下是我从官网翻译过来的. http://kudu.apache.org/docs/installation.html# ...
- POJ 3189——Steady Cow Assignment——————【多重匹配、二分枚举区间长度】
Steady Cow Assignment Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I ...
- POJ 1860——Currency Exchange——————【最短路、SPFA判正环】
Currency Exchange Time Limit:1000MS Memory Limit:30000KB 64bit IO Format:%I64d & %I64u S ...
- H-ui出现提交后没办法关闭
可以用sublime代替服务器来解决,或者是webstorm可以自行搭建服务器来解决当前的问题. sublime可以更改端口号 自己加上一个服务器 默认打开浏览器的 “快捷键”
- 利用jquery给指定的table动态添加一行、删除一行,复制,值不重复等操作
$("#mytable tr").find("td:nth-child(1)") 1表示获取每行的第一列$("#mytable tr").f ...