题目链接:

https://jzoj.net/senior/#main/show/6092

题目:

知识点--平面图转对偶图

在求最小割的时候,我们可以把平面图转为对偶图,用最短路来求最小割,这样会比dinic更快,但只是只用于网格图

网格图(平面图),即满足可以画在平面,且任意两条边的交点只能是边的顶点的图

性质:一个联通的平面图有$n$个点,$m$条边,$f$个面,那么有$f=m-n+2$

对于一个平面图,我们可以找到它的对偶图。做法是把每一个分割出来的面作为一个个顶点,两个面之间存在边并且仅当这两个面在原图中存在公共边,新连的边的边权就是公共边的边权

如图为例

我们在下面找一个点$s*$,在上面找一个$t*$,在源点与汇点之间跑最短路即为原图的最小割。这个结论看起来蛮显然的

注意$s*$和$t*$要视情况而定来寻找(个人看法,我也没写过几道这样的题目,一般而言$dinic$优化一下就足够了)

那么如何把平面图转为对偶图呢?

我们对原图每一个点把连着它的边做极角排序。然后我们考虑一条边(有向),强制让它顺时针或者逆时针方向(这个都可以,但是每一条边定义的方向是要一样的,接下来就按顺时针来叙述),这样的话它的反向边就会朝另外一个方向,于是这样两个平面就建立起了双向边

其实最难的还是如何确定一个平面。设一条边起点为$u$,终点为$v$,这条边为$l$,做法是在顺时针转后在找到相对于v而言极角比l大的第一条边,很显然这样找到的边$r$和之前的边$l$就是同一个平面的两条相邻的边,那么我们就记下$nxt[l]=r$。弄完所有的边后,我们遍历每一条边并对取到的边标记,然后不断取$nxt$,知道取到又取到标记的边为止,这样我们就找到了一个面。口述比较难以理解,代码通俗易懂。值得注意的是这样我们也会把那个外面的无穷大平面找到

题解:

  • 先把平面图转化为对偶图,在转化的过程中就可以算出每个平面的光明值和黑暗值,当然无限大的平面也可以算出
  • 我们建一个超级源点S和一个超级汇点T,S向每个面连有向边,容量为其光明值,每个面向T连有向边,容量为其黑暗值。相邻的面之间连的是无向边,容量为其交边的c值
  • 很显然答案为所有面的光明值和黑暗值之和减去这张图的最小割
  • 归纳:这样每个元素有两个选择的很多都可以转化为最小割模型。并且由于最小割是最小化,若答案是最大化的化总是要用总的减去最小割的值(如最大权闭合子图模型)

代码:

#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
typedef double db; const int N=1e5+;
const int M=5e5+;
const ll inf=1e18;
int n,m;
inline char gc() {
static char buf[],*p1,*p2;
if (p1==p2) p1=(p2=buf)+fread(buf,,,stdin);
return p1==p2?EOF:*p2++;
}
inline ll read()
{
char ch=gc();ll s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=gc();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=gc();}
return s*f;
}
struct Point
{
int x,y,a,b;
}p[N];
struct EDGE
{
int u,v,c;
}edge[N<<];
vector <int> t[N];
bool cmp(int a,int b)
{
int x1=p[edge[a].v].x-p[edge[a].u].x,y1=p[edge[a].v].y-p[edge[a].u].y;
int x2=p[edge[b].v].x-p[edge[b].u].x,y2=p[edge[b].v].y-p[edge[b].u].y;
return atan2((db)y1,(db)x1)<atan2((db)y2,(db)x2);
}
int tot;
int vis[M],nxt[M],bel[M];
ll gms[M],has[M];
int cnt=,T,S;
int head[M];
ll sum;
struct E
{
int to,nxt;
ll cap;
}e[M];
void adde(int u,int v,int c)
{
e[++cnt]=(E){v,head[u],c};
head[u]=cnt;
}
void insert(int u,int v,int c)
{
adde(u,v,c);adde(v,u,);
}
void build()//平面图转对偶图
{
for (int i=;i<=n;i++) sort(t[i].begin(),t[i].end(),cmp);
for (int i=;i<(m<<);i++)
{
int v=edge[i].v;
vector<int>::iterator it=++lower_bound(t[v].begin(),t[v].end(),i^,cmp);
if (it==t[v].end()) it=t[v].begin();
nxt[i]=*it;
}
for (int i=;i<(m<<);i++) if (!vis[i])
{
++tot;
for (int j=i;!vis[j];j=nxt[j]) vis[j]=,bel[j]=tot;
}
//网络流建图
for (int i=;i<(m<<);i++)
{
int u=bel[i],v=bel[i^],c=edge[i].c;
gms[u]+=1ll*p[edge[i].u].a;has[u]+=1ll*p[edge[i].u].b;
if (u>v) continue;
adde(u,v,c);adde(v,u,c);
}
S=tot+;T=tot+;
for (int i=;i<=tot;i++)
{
sum+=gms[i]+has[i];
insert(S,i,gms[i]);
insert(i,T,has[i]);
}
}
queue <int> q;
int dep[M];
int bfs()
{
while (!q.empty()) q.pop();
memset(dep,,sizeof(dep));
dep[S]=;
q.push(S);
while (!q.empty())
{
int k=q.front();q.pop();
for (int i=head[k];i;i=e[i].nxt)
{
int y=e[i].to;
if (e[i].cap&&!dep[y])
{
dep[y]=dep[k]+;
q.push(y);
}
}
}
return dep[T];
}
int cur[M];
ll dfs(int x,ll a)
{
if (x==T||!a) return a;
ll f,flow=;
for (int &i=cur[x];i;i=e[i].nxt)
{
int y=e[i].to;
if (dep[y]==dep[x]+&&(f=dfs(y,min(e[i].cap,a)))>)
{
flow+=f;
a-=f;
e[i].cap-=f;
e[i^].cap+=f;
if (!a) break;
}
}
return flow;
}
ll dinic()
{
ll res=;
while (bfs())
{
memcpy(cur,head,sizeof(head));
res+=dfs(S,inf);
}
return res;
}
int main()
{
freopen("everfeel.in","r",stdin);
freopen("everfeel.out","w",stdout);
int NUM=read();
n=read();m=read();
for (int i=;i<=n;i++) p[i].x=read(),p[i].y=read(),p[i].a=read(),p[i].b=read();
for (int i=;i<m;i++)
{
int u=read(),v=read(),c=read();
edge[i<<]=(EDGE){u,v,c};edge[i<<|]=(EDGE){v,u,c};
t[u].push_back(i<<);t[v].push_back(i<<|);
}
build();
printf("%lld\n",sum-dinic());
return ;
}

[jzoj 6092] [GDOI2019模拟2019.3.30] 附耳而至 解题报告 (平面图转对偶图+最小割)的更多相关文章

  1. [jzoj 6086] [GDOI2019模拟2019.3.26] 动态半平面交 解题报告 (set+线段树)

    题目链接: https://jzoj.net/senior/#main/show/6086 题目: 题解: 一群数字的最小公倍数就是对它们质因数集合中的每个质因数的指数取$max$然后相乘 这样的子树 ...

  2. [jzoj 6093] [GDOI2019模拟2019.3.30] 星辰大海 解题报告 (半平面交)

    题目链接: https://jzoj.net/senior/#contest/show/2686/2 题目: 题解: 说实话这题调试差不多花了我十小时,不过总算借着这道题大概了解了计算几何的基础知识 ...

  3. [jzoj 4528] [GDOI2019模拟2019.3.26] 要换换名字 (最大权闭合子图)

    题目链接: https://jzoj.net/senior/#contest/show/2683/0 题目: 题解: 不妨枚举一个点,让两颗树都以这个点为根,求联通块要么点数为$0$,要么包括根(即联 ...

  4. [jzoj 6101] [GDOI2019模拟2019.4.2] Path 解题报告 (期望)

    题目链接: https://jzoj.net/senior/#main/show/6101 题目: 题解: 设$f_i$表示从节点$i$到节点$n$的期望时间,$f_n=0$ 最优策略就是如果从$i, ...

  5. [jzoj 6080] [GDOI2019模拟2019.3.23] IOer 解题报告 (数学构造)

    题目链接: https://jzoj.net/senior/#main/show/6080 题目: 题意: 给定$n,m,u,v$ 设$t_i=ui+v$ 求$\sum_{k_1+k_2+...+k_ ...

  6. [jzoj 6087] [GDOI2019模拟2019.3.26] 获取名额 解题报告 (泰勒展开+RMQ+精度)

    题目链接: https://jzoj.net/senior/#main/show/6087 题目: 题解: 只需要统计$\prod_{i=l}^r (1-\frac{a_i}{x})$ =$exp(\ ...

  7. [jzoj 6084] [GDOI2019模拟2019.3.25] 礼物 [luogu 4916] 魔力环 解题报告(莫比乌斯反演+生成函数)

    题目链接: https://jzoj.net/senior/#main/show/6084 https://www.luogu.org/problemnew/show/P4916 题目: 题解: 注: ...

  8. [JZOJ 5908] [NOIP2018模拟10.16] 开荒(kaihuang)解题报告 (树状数组+思维)

    题目链接: https://jzoj.net/senior/#contest/show/2529/1 题目: 题目背景:尊者神高达作为一个萌新,在升级路上死亡无数次后被一只大黄叽带回了师门.他加入师门 ...

  9. [JZOJ 5909] [NOIP2018模拟10.16] 跑商(paoshang) 解题报告 (圆方树)

    题目链接: https://jzoj.net/senior/#contest/show/2529/2 题目: 题目背景:尊者神高达很穷,所以他需要跑商来赚钱题目描述:基三的地图可以看做 n 个城市,m ...

随机推荐

  1. redis的跳跃表

    跳跃表是一种插入.查询.删除的平均时间复杂度为O(nlogn)的数据结构,在最差情况下是O(n),当然这几乎很难出现. 和红黑树相比较 最差时间复杂度要差很多,红黑树是O(nlogn),而跳跃表是O( ...

  2. Python中OpenCV2. VS. CV1

    OpenCV的2.4.7.版本生成了python的CV2模块,可以直接载入: 有兴趣的可以参考这个教程:http://blog.csdn.net/sunny2038/article/details/9 ...

  3. python版本及ML库

    一:关于Python版本的选择问题 关于Python的选择问题:要看学术界能不能把科学库迁移到Python3. 1:多个版本共用: 最近发现SciPy的最高版本是3.2,只能是退而求其次,不使用最新版 ...

  4. AndroidStudio/Intellij 快捷键

    说明 三年来一直使用Eclipse作为自己的IDE, 现在是时候走出自己的safety zone, 开始使用传说中的Intellij了. Eclipse/Intellij IDE环境为: OS X 1 ...

  5. (转)基于MVC4+EasyUI的Web开发框架经验总结(7)--实现省份、城市、行政区三者联动

    http://www.cnblogs.com/wuhuacong/p/3841338.html 为了提高客户体验和进行一些技术探索,现在正准备把我自己的客户关系管理系统CRM在做一个Web的版本,因此 ...

  6. BZOJ 1042: [HAOI2008]硬币购物 容斥原理_背包_好题

    Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买s i的价值的东西.请问每次有多少种付款方法. 题解: 十分喜 ...

  7. 路飞学城Python-Day181

    Evernote Export Nginx默认网站 当Nginx配置文件中有且仅有一个Server的时候,该Server就被Nginx认为是默认网站,所有发给Nginx服务器80端口的数据都会默认给s ...

  8. github下载报错:Permission denied (publickey). fatal: Could not read from remote repository.

    Permission denied (publickey). fatal: Could not read from remote repository. 博主在github上下载tiny face的的 ...

  9. [网络流24题] 最长k可重区间集问题 (费用流)

    洛谷传送门 LOJ传送门 很巧妙的建图啊...刚了$1h$也没想出来,最后看的题解 发现这道题并不类似于我们平时做的网络流题,它是在序列上的,且很难建出来二分图的形. 那就让它在序列上待着吧= = 对 ...

  10. BA-设计施工调试流程

    工程范围 1.楼宇自控系统的工程设计首先要了解目标建筑物所处的地理环境.建筑物用途.楼宇自控系统的建设目标定位.建筑设备规模与控制工艺及监控范围等工程情况.这些情况一般在工程招标技术文件中介绍,设计者 ...