平面图转对偶图&19_03_21校内训练 [Everfeel]
对于每个平面图,都有唯一一个对偶图与之对应。若G‘是平面图G的对偶图,则满足:
G'中每一条边的两个节点对应着G中有公共边的面,包括最外部无限大的面。
直观地讲,红色标出来的图就是蓝色标出的图的对偶图。

求出一个平面图的对偶图(而且不是特殊的结构),可以贪心地找出所有最小的面。但如何描述最小?我们要固定一条边,按它顺时针或逆时针的方向找到第一条边,直到出现第一个访问过的边,就找到了一个面。
具体地将:从每个边出发,按有方向的角排序,找到角度最大或最小的边,再进行下去。反正自己写写代码就知道了。

例题
给出一个平面图,每个点有a和b两种属性,每个面(包括无限大的面)的价值为在这个面上的点的a总和或b总和,若相邻的面所选的属性不同,代价为所有相邻点边的点权和。最大化总价值。N≤4000。
思路
考场上从没写过对偶图,结果自己搞出来了.......反而最小割没写出来。
转完对偶图后,从S向每个对偶图上的点连一条比边权为该面的a价值总和的边,再从这个点向T连一条边权为该面的b价值总和的边。对于原图相邻的面,连一条权值为公共边价值和的边(这个要双向)。不难发现其最小割为最小的代价。
如:
重复的边合并即可。
一个不需要代码的代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const double pi=3.1415926535898;
const ll maxn=2E5+;
const ll inf=INT_MAX;
ll min(ll x,ll y){return x<y?x:y;}
struct pt
{
double x,y;
int pos;
pt(double a=,double b=,int p=){x=a,y=b;pos=p;}
void operator=(pt A){x=A.x,y=A.y,pos=A.pos;}
pt operator+(pt A){return pt(x+A.x,y+A.y,pos);}
pt operator-(pt A){return pt(x-A.x,y-A.y,pos);}
void out(){cout<<x<<" "<<y<<" ";}
}p[maxn];
ll n,m,v[maxn][],x,y,z,cur,val[maxn][],ans,dfn[maxn],ti,S,T;
bool vis[maxn*];
map<int,int>next;
map<pair<int,int>,int>cost;
set<pair<int,int> >eS;
pt rotate(pt A,double ra){return pt(A.x*cos(ra)-A.y*sin(ra),A.x*sin(ra)+A.y*cos(ra),A.pos);}
pt wait[maxn];
bool cmp(pt A,pt B)
{
double r1=atan2(A.y,A.x);
double r2=atan2(B.y,B.x);
if(r1<)r1+=*pi;
if(r2<)r2+=*pi;
return r1<r2;
}
struct edge{ll to,next,from,w,bel;};
struct graph
{
int head[maxn*],size;
graph(){size=;}
edge E[maxn*];
void add(int u,int v,ll w)
{
E[++size].to=v;
E[size].next=head[u];
E[size].w=w;
E[size].from=u;
head[u]=size;
}
void sortAngle(pt A,pt B,int r,int num)//suppose that A is the centre
{
B=B-A;
double ra=-atan2(B.y,B.x);
B=rotate(B,ra);
for(int i=;i<=r;++i)wait[i]=rotate(wait[i]-A,ra);
sort(wait+,wait+r+,cmp);
next[num]=wait[].pos;
for(int i=;i<r;++i)
next[wait[i].pos^]=wait[i+].pos;
next[wait[r].pos^]=num^;
}
void sortAll()
{
for(int i=;i<=size;++i)
{
if(next[i]==)
{
int L=;
for(int j=head[E[i].to];j;j=E[j].next)
{
if(E[j].to==E[i].from)continue;
wait[++L]=p[E[j].to];
wait[L].pos=j;
}
sortAngle(p[E[i].to],p[E[i].from],L,i);
}
}
}
void dfs(int i,int pos)
{
ans+=v[E[i].to][];
ans+=v[E[i].to][];
vis[i]=;
E[i].bel=pos;
val[pos][]+=v[E[i].to][];
val[pos][]+=v[E[i].to][];
i=next[i];
if(vis[i])return;
dfs(i,pos);
}
void getVal()
{
sortAll();
for(int i=;i<=size;++i)
if(!vis[i])
{
++cur;
dfs(i,cur);
}
}
bool bfs()
{
for(int i=;i<=T;++i)dfn[i]=-;
dfn[S]=;
queue<int>Q;
Q.push(S);
while(Q.size())
{
int u=Q.front();
Q.pop();
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(dfn[v]!=-||E[i].w==)continue;
dfn[v]=dfn[u]+;
Q.push(v);
}
}
return dfn[T]!=-;
}
ll dinic(int u,ll up)
{
if(u==T)return up;
ll sum=;
for(int i=head[u];i;i=E[i].next)
{
int v=E[i].to;
if(dfn[v]!=dfn[u]+||E[i].w==)continue;
ll g=dinic(v,min(E[i].w,up-sum));
E[i].w-=g;
E[i^].w+=g;
sum+=g;
if(g==)dfn[v]=-;
if(sum==up)break;
}
return sum;
}
}G,flow;
int main()
{
freopen("everfeel.in","r",stdin);
freopen("everfeel.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n>>n>>m;
for(int i=;i<=n;++i)
cin>>p[i].x>>p[i].y>>v[i][]>>v[i][];
for(int i=;i<=m;++i)
{
cin>>x>>y>>z;
G.add(x,y,z);
G.add(y,x,z);
}
G.getVal();
S=;
T=cur+;
for(int i=;i<=G.size;i+=)
{
pair<int,int>P=make_pair(G.E[i].bel,G.E[i^].bel);
cost[P]+=G.E[i].w;
eS.insert(P);
}
for(set<pair<int,int> >::iterator pos=eS.begin();pos!=eS.end();++pos)
{
flow.add(pos->first,pos->second,cost[*pos]);
flow.add(pos->second,pos->first,cost[*pos]);
}
for(int i=;i<=cur;++i)
{
flow.add(S,i,val[i][]);
flow.add(i,S,);
flow.add(i,T,val[i][]);
flow.add(T,i,);
}
ll sum=;
while(flow.bfs())sum+=flow.dinic(S,inf);
cout<<ans-sum<<endl;
return ;
}
平面图转对偶图&19_03_21校内训练 [Everfeel]的更多相关文章
- [jzoj 6092] [GDOI2019模拟2019.3.30] 附耳而至 解题报告 (平面图转对偶图+最小割)
题目链接: https://jzoj.net/senior/#main/show/6092 题目: 知识点--平面图转对偶图 在求最小割的时候,我们可以把平面图转为对偶图,用最短路来求最小割,这样会比 ...
- 【BZOJ-2007】海拔 最小割 (平面图转对偶图 + 最短路)
2007: [Noi2010]海拔 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2095 Solved: 1002[Submit][Status] ...
- 平面图转对偶图(Bzoj1001:狼抓兔子)
如果只会用最小割做这道题那就太菜辣 引入 来自某学长 平面图:在平面上边不相交的图(边可以绕着画) 那么平面图的边与边就围成了许多个区域(这与你画图的方式有关) 定义对偶图:把相邻的两个区域连上边,形 ...
- bzoj3051[WC2013]平面图(树上倍增+平面图转对偶图+扫描线)
简要题意:二维平面上n个点,点之间有一些连线,连线不在点之外的地方相交,将平面分为若干个区域.给出一些询问点对,问从这个点所在的区域走到另一个点所在的区域的最小代价. 题解:这道题首先可以把平面图转对 ...
- LOJ#2052. 「HNOI2016」矿区(平面图转对偶图)
题面 传送门 题解 总算会平面图转对偶图了-- 首先我们把无向边拆成两条单向边,这样的话每条边都属于一个面.然后把以每一个点为起点的边按极角排序,那么对于一条边\((u,v)\),我们在所有以\(v\ ...
- 【BZOJ2007】【NOI2010】海拔(最小割,平面图转对偶图,最短路)
[BZOJ2007][NOI2010]海拔(最小割,平面图转对偶图,最短路) 题面 BZOJ 洛谷 Description YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域. ...
- 【BZOJ1001】狼抓兔子(平面图转对偶图,最短路)
[BZOJ1001]狼抓兔子(平面图转对偶图,最短路) 题面 BZOJ 洛谷 题解 这题用最小割可以直接做 今天再学习了一下平面图转对偶图的做法 大致的思路如下: 1.将源点到汇点中再补一条不与任何线 ...
- 【BZOJ 2007】 2007: [Noi2010]海拔 (平面图转对偶图+spfa)
2007: [Noi2010]海拔 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2504 Solved: 1195 Description YT市 ...
- 【BZOJ】2007: [Noi2010]海拔(平面图转对偶图)
题目 传送门:QWQ 分析 左上角是0,右下角是1.那么大概整张图是由0 1构成的. 那么我们要找到0和1的分界线,值就是最小割. 然后变成求原图最小割. 考虑到此题是平面图,那么就转成对偶图跑最短路 ...
随机推荐
- Linux 中 MySQL常用命令
一. 数据库登录mysql -uroot -p二..退出数据库quit 和 exit或ctrl + d三.数据库操作1. 查看所有数据库 show databases;2. 查看当前使用的数据库sel ...
- c# 写入Xml 元素(<![CDATA[ ]]>)
一般处理程序代码: XmlDocument xmldoc = new XmlDocument(); xmldoc.AppendChild(xmldoc.CreateXmlDec ...
- 响应式图片 (responsive image)
更新 : 2019-02-21 除了写 srcset sizes 还有一种 x1, x2, x3, x4 的写法. 我们对比一下 假设 pc 希望是 1000w mobile 希望是 300w siz ...
- BGP - 2,BGP报文和BGP状态
1,BGP报文 Open:建邻居,交换version.AS号.holdtime.BGP identifier(即RouterID).可选参数长度.可选参数. Keepalive:保 ...
- 【洛谷p1031】均分纸牌
[博客园的第一条随笔,值得纪念一下] 均分纸牌[传送门] 洛谷上的算法标签是 这道题是一道贪心题,过了四遍才过(蒟蒻有点废) 第一遍的时候考虑的非常少,只想到了求出平均数→求差值→从左往右加差值: 这 ...
- python基础之循环语句,格式化输出以及编码
1.while循环语句 1.1 常见的几种结构 1. while+判断条件 循环体 2. while+判断条件 循环体 else 语句 tips:while循环如果满足条件的话,会一直循环循环体 ...
- python记录_day10 动态传参 命名空间 作用域
一.动态传参 动态传参用到 *args 和 **kwargs ,*号表示接收位置参数,args是参数名:**表示接收关键字参数,kwargs是参数名 def chi(*food): print(foo ...
- Leetcode 1004. 最大连续1的个数 III
1004. 最大连续1的个数 III 显示英文描述 我的提交返回竞赛 用户通过次数97 用户尝试次数143 通过次数102 提交次数299 题目难度Medium 给定一个由若干 0 和 1 组成 ...
- System.Web.Optimization 找不到引用,教你如何解决?
在vs 2017 创建 BundleConfig 时添加引用 using System.Web.Optimization 是报错 提示未找到 解决方法: 在最下端窗口中写入:Install-Packa ...
- log4j的一些参数说明
参数 说明 例子 %c 列出logger名字空间的全称,如果加上{<层数>}表示列出从最内层算起的指定层数的名字空间 log4j配置文件参数举例 输出显示媒介 假设当前logger名字空间 ...