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, ...
随机推荐
- C++ vector类型要点总结(以及各种algorithm算法函数)
概述 C++内置的数组支持容器的机制,但是它不支持容器抽象的语义.要解决此问题我们自己实现这样的类.在标准C++中,用容器向量(vector)实现. 容器向量也是一个类模板.vector是C++标准模 ...
- springMVC初探视图解析器——InternalResourceViewResolver
springmvc在处理器方法中通常返回的是逻辑视图,如何定位到真正的页面,就需要通过视图解析器. springmvc里提供了多个视图解析器,InternalResourceViewResolver就 ...
- Access restriction: The type Base64 is not accessible due to restriction on
java build path>把libraries中的JRE System Library删除重新导入.
- 配置WAMP完美攻略
软件介绍 Wamp Server 是一款功能强大的PHP 集成安装环境. 为了节约时间,本次使用 Wamp Server 来进行配置. wamp 的全部含义就是本篇文章的标题. 使用版本和操作系统 W ...
- CSS3 中 图标编码 icon——Font-Awesome
在做网页开发中经常会用到图标,原来经常会到一些icon网站上找导入到项目中,现在Font-Awesome中的有很多的图标,并且还在不断更新 现在Font-Awesome最新版本是4.7,下载出来的Fo ...
- java多线程(一)
一.进程,线程,并发,并行 1.1 进程和线程的区别 进程是指:一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程.比如在Windows系统中,一个运 ...
- WebStorm 预览时把浏览器地址localhost 改成IP
最近在使用WebStorm时,预览网页时地址总是显示的 http://localhost:63342/... ,如果要调试其它设备感觉很不方法,此时肯定首先想到的亲爱的度娘,但是貌似没有真正很解决问题 ...
- Technical Committee Weekly Meeting 2016.06.21
Meeting time: 2016.June.21 1:00~2:00 Chairperson: Thierry Carrez Meeting summary: 1.Add current hou ...
- Eclipse中引来的jar包乱码
Eclipse中引入的jar包乱码jar包链接的源码,中文注释为乱码的解决方法: 1.将Eclipse的Preferences中的General>ContentTypes中的Java Class ...
- Deferred跟promise跟js同步问题记录
之前的时候,碰到过几次同事问我,说js的同步怎么处理,就是我想先执行这段代码(耗时相对较长的一行,多数是异步的一些api调用),执行完了之后我再执行下边这句,每次我都很无奈的说不晓得,如果是ajax的 ...