BZOJ2960:跨平面
题面
Sol
对该平面图的对偶图建图后就是最小树形图,建一个超级点向每个点连 \(inf\) 边即可
怎么转成对偶图,怎么弄出多边形
把边拆成两条有向边,分别挂在两个点上
每个点的出边按角度排序
每次选择一个没有标记过的边做 \(DFS\)
从 \(u\) 到 \(v\),然后 \(v\) 选择 \((v,u)\) 顺时针转的下一条边,最后跑到原来的点,此时一定有一个多边形形成,记录编号后标记在边上即可
# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
}
const int maxn(100005);
const int inf(1e9);
namespace MST{
int n, cnt, pre[maxn], vis[maxn], id[maxn], ans, inw[maxn], sum, rt;
struct Edge{
int u, v, w;
} e[maxn];
IL void Add(RG int u, RG int v, RG int w){
e[++cnt] = (Edge){u, v, w};
}
IL int DirectedMST(){
for(RG int i = 1; i <= cnt; ++i) sum += e[i].w;
ans -= (++sum);
for(RG int i = 1; i <= n; ++i) Add(n + 1, i, sum);
rt = ++n;
while(true){
RG int idx = 0;
for(RG int i = 1; i <= n; ++i) pre[i] = id[i] = vis[i] = -1, inw[i] = inf;
for(RG int i = 1; i <= cnt; ++i)
if(e[i].u != e[i].v && e[i].w < inw[e[i].v]) inw[e[i].v] = e[i].w, pre[e[i].v] = e[i].u;
inw[rt] = 0, pre[rt] = rt;
for(RG int i = 1; i <= n; ++i){
ans += inw[i];
if(vis[i] == -1){
RG int x = i;
while(vis[x] == -1) vis[x] = i, x = pre[x];
if(x != rt && vis[x] == i){
id[x] = ++idx;
for(RG int j = pre[x]; j != x; j = pre[j]) id[j] = idx;
}
}
}
if(!idx) break;
for(RG int i = 1; i <= n; ++i) if(id[i] == -1) id[i] = ++idx;
for(RG int i = 1; i <= cnt; ++i)
e[i].w -= inw[e[i].v], e[i].u = id[e[i].u], e[i].v = id[e[i].v];
n = idx, rt = id[rt];
}
return ans;
}
}
struct Line{
int u, v, id, type;
double k;
IL int operator <(RG Line b) const{
return k < b.k;
}
} line[maxn];
struct Point{
int x, y;
} a[maxn];
struct Edge{
int u, v, next, type, id;
} edge[maxn];
int n, m, num, first[maxn], cnt, mat[2][maxn], vis[maxn], val[2][maxn];
IL void Add(RG int u, RG int v, RG int type, RG int id){
edge[cnt] = (Edge){u, v, first[u], type, id}, first[u] = cnt++;
}
IL int Dfs(RG int u, RG int ff){
if(vis[u]) return ++MST::n;
for(RG int e = first[u]; e != -1; e = edge[e].next){
RG int v = edge[e].v, id, type;
if(v == ff){
e = edge[e].next;
if(e == -1) e = first[u];
v = edge[e].v, id = edge[e].id, type = edge[e].type;
return mat[type][id] = Dfs(v, u);
}
}
return 0;
}
int main(){
n = Input(), m = Input();
for(RG int i = 1; i <= n; ++i) first[i] = -1;
for(RG int i = 1; i <= n; ++i) a[i].x = Input(), a[i].y = Input();
for(RG int i = 1, x, y; i <= m; ++i){
x = Input(), y = Input(), val[0][i] = Input(), val[1][i] = Input();
line[++num] = (Line){x, y, i, 0}, line[num].k = atan2(a[y].y - a[x].y, a[y].x - a[x].x);
line[++num] = (Line){y, x, i, 1}, line[num].k = atan2(a[x].y - a[y].y, a[x].x - a[y].x);
}
sort(line + 1, line + num + 1);
for(RG int i = 1; i <= num; ++i) Add(line[i].u, line[i].v, line[i].type, line[i].id);
for(RG int i = 0; i < cnt; ++i)
if(!mat[edge[i].type][edge[i].id]){
vis[edge[i].u] = 1;
mat[edge[i].type][edge[i].id] = Dfs(edge[i].v, edge[i].u);
vis[edge[i].u] = 0;
}
for(RG int i = 1; i <= m; ++i){
if(val[0][i]) MST::Add(mat[0][i], mat[1][i], val[0][i]);
if(val[1][i]) MST::Add(mat[1][i], mat[0][i], val[1][i]);
}
printf("%d\n", MST::DirectedMST());
return 0;
}
BZOJ2960:跨平面的更多相关文章
- BZOJ2960: 跨平面
从一条边出发遍历,每次找旋转角度最小的一条边作为下一条边,直到回到出发的边,就得到了一个区域.这样建出对偶图后跑不定根的最小树形图就行了. #include<bits/stdc++.h> ...
- 高速LVDS电平简介
一.LVDS简介 1.1.LVDS信号介绍LVDS:Low Voltage Differential Signaling,低电压差分信号.LVDS传输支持速率一般在155Mbps(大约为77MHZ)以 ...
- PCB设计工程师面试题
网上的一套PCB设计工程师面试题,测下你能不能拿90分? [复制链接] 一.填空 1.PCB上的互连线按类型可分为()和() . 2.引起串扰的两个因素是()和(). 3.EMI ...
- layout焊盘过孔大小的设计标准
PCB设计前准备 1.准确无误的原理图.包括完整的原理图文件和网表,带有元件编码的正式的BOM.原理图中所有器件的PCB封装(对于封装库中没有的元件,硬件工程师应提供datasheet或者实物,并指定 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 最小割&网络流应用
重要链接 基础部分链接 : 二分图 & 网络流初步 zzz大佬博客链接 : 网络流学习笔记 重点内容:最小割二元关系新解(lyd's ppt) 题目:网络流相关题目 lyd神犇课件链接 : 网 ...
- 平面内,线与线 两条线找交点 两条线段的位置关系(相交)判定与交点求解 C#
个人亲自编写.测试,可以正常使用 道理看原文,这里不多说 网上找到的几篇基本都不能用的 C#代码 bool Equal(float f1, float f2) { return (Math ...
- 在路上:安全公司“跨界”SD-WAN
编者按:本文是SDNLAB“企业+”特别报道之一.“企业+”是SDNLAB重点打造的栏目,汇聚信息行业运营商.设备商.互联网公司.软件公司.集成公司.融创投资公司.科研院所等企业,重新定义IT行业撮合 ...
- Luogu P1429 平面最近点对 【分治】By cellur925
题目传送门 题目大意:给定平面上n个点,找出其中的一对点的距离,使得在这n个点的所有点对中,该距离为所有点对中最小的.$n$<=100000. $Algorithm$ 最朴素的$n^2$枚举肯定 ...
随机推荐
- CUDA安装
1.CUDA是什么? CUDA(Compute Unified Device Architecture),显卡厂商NVidia推出的运算平台. 随着显卡的发展,GPU越来越强大,而且GPU为显示图像做 ...
- VS 代码自动对齐快捷键
全部代码代码自动对齐快捷键为 Ctrl + a(按后可松松手) + k(按后可松松手) + f
- (四)Audio子系统之AudioRecord.read
在上一篇文章<(三)Audio子系统之AudioRecord.startRecording>中已经介绍了AudioRecord如何开始录制音频,接下来,继续分析AudioRecord方 ...
- python怎么解决用matplotlib画图时无法显示中文的问题或者出现方框的问题
在中文前面加上u 加上u以后如果还不可以显示中文显示了方框 就直接加上 from pylab import mpl mpl.rcParams['font.sans-serif']=['SimHei']
- 写在学习Oracle之前
好久没有更新我的博客了,主要是因为年前换了工作.新工作比较忙,很少时间来博客园了. 作为Android开发人员,我为什么要学习Oracle数据库呢?我是非计算机专业出身,大学没有学习过任何关于数据库和 ...
- Mac下的裁剪快捷键
按[Command]+[C]复制文件,然后按[Command]+[Option]+[V]. 注意:[Command]+[X]只能剪切文字文本.
- LINQ to Entities does not recognize the method , and this method cannot be translated into a store expression 解决办法
根据用户输入的起始日期,查询以起始日期开始的前20条记录,在ASP.NET MVC的Controller代码中这样写: var Logs = db.Log.Take(20); if (!string. ...
- shiro学习笔记_0200_认证
认证,身份验证,验证用户是否合法 在shiro中,用户需要提供principals (身份)和credentials(证明)给shiro,从而应用能验证用户身份: principals:用户的身份信息 ...
- orcale 之pl/sql例外
orcale 中的例外我们可以看作是其他编程语言中的异常,是为了增强语言的健壮性和容错性. 在orcale中常见的有以下几种: No_data_found 很容易理解就是没有数据返回. Too_man ...
- WPF 自定义NotifyPropertyChanged
该工具类实现INotifyPropertyChanged接口 /// <summary> /// 实现了属性更改通知的基类 /// </summary> public clas ...