平面图转对偶图&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的分界线,值就是最小割. 然后变成求原图最小割. 考虑到此题是平面图,那么就转成对偶图跑最短路 ...
随机推荐
- ftp服务器搭建(离线安装vsftpd),配置
1.下载vsftp:http://rpmfind.net/linux/rpm2html/search.php?query=vsftpd(x86-64) 2.检查是否已经安装了vsftp rpm -qa ...
- cocos2dx spine之二 :spine变色
cocos2dx版本为3.10 1.具体原理和代码可以参考博文<利用shader改变图片色相Hue>,下面的代码根据该博文进行整理优化. 基本原理就是将RGB值转换为HSL值后加上输入的H ...
- pytorch-1.0 踩坑记录
参加百度的一个竞赛,官方要求把提交的代码测试环境pyorch1.0,于是将自己计算机pytorch升级到1.0. 在ubuntu下用conda install pytorch 命令安装时,效果很差,解 ...
- ubuntu 16.04 下安装smplayer视频播放器
安装平台:ubuntu 16.04 1.sudo apt-add-repository ppa:rvm/smplayer 2.sudo apt-get update 3.sudo apt-get in ...
- springmvc如何进行热部署开发
1.场景还原 在工程量大的情况下,tomcat运行部署一次会花费相当多的时间,这样太 浪费人力以及时间了:今天笔者将 讲解一下如何配置springmvc工程的热部署 2.实现方案 其实很简单! ①在t ...
- php oracle数据库NCOLB字段ORA-01704
php oracle数据库NCOLB字段ORA-01704 对clob更新 ORA-01704: 字符串文字太长 解决办法:把字符赋值给一个变量,然后赋值update语句 declarev_clob ...
- English trip V1 - 10.Family Ties 家庭关系 Teacher:Emily Key: Possessive s (所有格 s)
In this lesson you will learn to talk about people in a family. 课上内容(Lesson) What are you Spring Fes ...
- 【调试】Idea如何远程debug之SpringBoot jar包启动
一.Java -jar启动添加如下参数 -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address= -Xdebug是通知JVM工 ...
- LeetCode--443--压缩字符串(未看)
问题描述: 给定一组字符,使用原地算法将其压缩. 压缩后的长度必须始终小于或等于原数组长度. 数组的每个元素应该是长度为1 的字符(不是 int 整数类型). 在完成原地修改输入数组后,返回数组的新长 ...
- You Don't Know JS: Scope & Closures (第3章: 函数 vs 块作用域)
第二章,作用域由一系列的bubbles组成.每一个都代表了一个container或bucket,装着被声明的identifiers(variables, functions).这些bubbles相互嵌 ...