Hubtown

时间限制: 1 Sec  内存限制: 128 MB
提交: 23  解决: 11
[提交] [状态] [讨论版] [命题人:admin]

题目描述

Hubtown is a large Nordic city which is home to n citizens. Every morning, each of its citizens wants to travel to the central hub from which the city gets its name, by using one of the m commuter trains which pass through the city. Each train line is a ray (i.e., a line segment which extends infinitely long in one direction), ending at the central hub, which is located at coordinates (0, 0). However, the train lines have limited capacity (which may vary between train lines), so some train lines may become full, leading to citizens taking their cars instead of commuting. The city council wishes to minimize the number of people who go by car. In order to do this, they will issue instructions stating which citizens are allowed to take which train. 
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 first line of input contains two integers n and m, where 0 ≤ n ≤ 200 000 is the number of citizens, and 1 ≤ m ≤ 200 000 is the number of train lines.
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.

输出

First, output a single integer s – the maximum number of citizens who can go by train. Then,output s lines, one for each citizen that goes by train. On each line, output the index of the citizen followed by the index of the train line the citizen takes. The indices should be zero-indexed (i.e.,between 0 and n − 1 for citizens, and between 0 and m − 1 for train lines, respectively), using the same order as they were given in the input.

样例输入

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(最大流)的更多相关文章

  1. Hubtown

    Hubtown 时间限制: 10 Sec  内存限制: 256 MB 题目描述 Hubtown is a large Nordic city which is home to n citizens. ...

  2. 使用C#处理基于比特流的数据

    使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...

  3. HTML 事件(三) 事件流与事件委托

    本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...

  4. FILE文件流的中fopen、fread、fseek、fclose的使用

    FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...

  5. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...

  6. java 字节流与字符流的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...

  7. BZOJ 3504: [Cqoi2014]危桥 [最大流]

    3504: [Cqoi2014]危桥 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1407  Solved: 703[Submit][Status] ...

  8. java I/O流

    输入流(读取数据的流) BufferedInputStream---继承--->FileInputStream--继承--->InputStream------> (1)字节流操作中 ...

  9. Ford-Fulkerson 最大流算法

    流网络(Flow Networks)指的是一个有向图 G = (V, E),其中每条边 (u, v) ∈ E 均有一非负容量 c(u, v) ≥ 0.如果 (u, v) ∉ E 则可以规定 c(u, ...

随机推荐

  1. 18-----BBS论坛

    BBS论坛(十八) 18.首页轮播图实现 (1)front/css/front_base.css .main-container{ width: 990px; margin: 0 auto; over ...

  2. 用dango框架搭建博客网站

    1.我早先下载了Anaconda35.0.1.但是Anaconda自带的编辑器Spyder我用的不太熟练.所以还是使用Pycharm来编辑代码.我的Pycharm试用期已经到了,所以需要注册码来使用P ...

  3. JS 中Math.ceil()、Math.floor()和Math.round()的区别

    var arg1 = 12.2; var arg2 = 12.5; var arg3 = 12.7; ceil():将小数部分一律向整数部分进位 var c1 = Math.ceil(arg1); v ...

  4. str 操作方法

    # str 类,字符串 # name ='alex' # 首字母变大写 # test ='alex' # v= test.capitalize() # print(v) # # 大写全部变小写 # t ...

  5. (转)Shell脚本之break,continue,和exit区别

    Linux脚本中的break continue exit return break结束并退出循环 continue在循环中不执行continue下面的代码,转而进入下一轮循环 exit退出脚本,常带一 ...

  6. LeetCode 110.平衡二叉树(C++)

    给定一个二叉树,判断它是否是高度平衡的二叉树. 本题中,一棵高度平衡二叉树定义为: 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1. 示例 1: 给定二叉树 [3,9,20,null,nu ...

  7. Git常用配置

    Git设置默认用户名和密码 1.进入C:\users\Administrator目录下,通过git bash终端输入touch .git-credentials后回车2.打开生成的.git-crede ...

  8. Ubuntu14.04-PXE搭建

    什么是PXE? PXE(Pre-boot Execution Environment,预启动执行环境)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持工作站通过网络从 ...

  9. HDU 5353—— Average——————【贪心+枚举】

    Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total S ...

  10. JQuery中的prop和attr

    prop和attr都可以用来获取并改变对象的属性, 对于HTML元素本身就带有的固有属性,在处理时,使用prop方法. 对于HTML元素我们自己自定义的DOM属性,在处理时,使用attr方法. 栗子: ...