Solution -「洛谷 P6158」封锁
\(\mathcal{Description}\)
Link.
给定一个 \(n\times n\) 的格点图,横纵相邻的两格点有一条边权为二元组 \((w,e)\) 的边。求对于 \(S=(1,1)\) 和 \(T=(n,n)\) 的一个割,使得 \((\sum w)(\sum c)\) 最小。
\(n\le400\)。
\(\mathcal{Solution}\)
套路题,P5540 + P4001。所以我把这两题题解合二为一。
假设边权都是普通的数字,考虑怎么快速求出这个格点图的最小割。可以发现,这个图一定是一个平面图,那么把它形象化为图形,脑补一下得出一个割肯定是一条完整的曲线,从图的左下方贯穿到图的右上方。所以建立左下方和右上方的超级源汇,每条边相当于连接其左右两个面,最后求源汇之间的最短路即为原图最小割。
回到本题,对于任意一个割,设其 \(\sum w=w_0\),\(\sum e=e_0\),将它体现为一个坐标 \((w_0,e_0)\),问题就转化为:\(\mathbb R^2\) 的一象限有若干个点,求出其中 \(xy\) 最小的点。
记 \(A(x_1,y_1)\) 为这些点中 \(x\) 最小的,\(B(x_2,y_2)\) 为 \(y\) 最小的(都能直接求出),考虑在 \(AB\) 的下方取出一个特殊的点 \(C(x_3,y_3)\),最大化 \(S_{\triangle ABC}\)。推一下式子:
S_{\triangle ABC}&=\frac{-\vec{AB}\times \vec{AC}}{2}\\
&=-\frac{1}{2}[(x_2-x_1)(y_3-y_1)-(x_3-x_1)(y_2-y_1)]\\
&=-\frac{1}2[(y_1-y_2)x_3+(x_2-x_1)y_3-x_2y_1+x_1y_2]
\end{aligned}
\]
把 \((y_1-y_2)w+(x_2-x_1)e\) 作为边 \((w,e)\) 的权,跑最小割即得 \(C\)。用 \(C\) 更新答案最后,分治处理 \((A,C)\) 和 \((C,B)\) 直到 \(C\) 不存在终止,答案就求到啦。
\(\mathcal{Code}\)
/* Clearink */
#include <queue>
#include <cstdio>
#include <assert.h>
typedef long long LL;
inline int rint () {
int x = 0, f = 1; char s = getchar ();
for ( ; s < '0' || '9' < s; s = getchar () ) f = s == '-' ? -f : f;
for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
return x * f;
}
inline void chkmin ( LL& a, const LL b ) { b < a && ( a = b, 0 ); }
const int MAXN = 400, INF = 0x3f3f3f3f;
int n, S, T;
LL coeW, coeE, ans = 1ll << 60;
struct Value {
LL w, e;
Value ( const LL v = 0 ): w ( v ), e ( v ) {}
Value ( const LL a, const LL b ): w ( a ), e ( b ) {}
inline operator LL () const { return w + e; }
inline LL operator * ( const Value& v ) const { return w * v.e - e * v.w; }
inline Value operator + ( const Value& v ) const { return { w + v.w, e + v.e }; }
inline Value operator - ( const Value& v ) const { return { w - v.w, e - v.e }; }
inline bool operator < ( const Value& v ) const {
return coeW * w + coeE * e < coeW * v.w + coeE * v.e;
}
};
typedef std::pair<Value, int> PVI;
struct Graph {
static const int MAXND = MAXN * MAXN + 2, MAXEG = 4 * MAXN * ( MAXN + 1 );
int bound, ecnt, head[MAXND + 5], to[MAXEG + 5], nxt[MAXEG + 5];
Value cst[MAXEG + 5], dist[MAXND + 5];
inline void operator () ( const int s, const int t, const Value& c ) {
#ifdef RYBY
printf ( "%d %d (%lld,%lld)\n", s, t, c.w, c.e );
#endif
to[++ecnt] = t, cst[ecnt] = c, nxt[ecnt] = head[s];
head[s] = ecnt;
to[++ecnt] = s, cst[ecnt] = c, nxt[ecnt] = head[t];
head[t] = ecnt;
}
inline Value dijkstra ( const int s, const int t ) {
static bool vis[MAXND + 5];
static std::priority_queue<PVI, std::vector<PVI>, std::greater<PVI> > heap;
for ( int i = 1; i <= bound; ++i ) vis[i] = false, dist[i] = INF;
heap.push ( { dist[s] = 0, s } );
while ( !heap.empty () ) {
PVI p ( heap.top () ); heap.pop ();
if ( vis[p.second] ) continue;
vis[p.second] = true;
for ( int i = head[p.second], v; i; i = nxt[i] ) {
if ( Value d ( p.first + cst[i] ); d < dist[v = to[i]] ) {
heap.push ( { dist[v] = d, v } );
}
}
}
return dist[t];
}
} graph;
inline int id ( const int i, const int j ) {
if ( !i || j == n ) return S;
if ( i == n || !j ) return T;
return ( i - 1 ) * ( n - 1 ) + j;
}
inline Value calc ( const LL a, const LL b ) {
coeW = a, coeE = b;
Value ret ( graph.dijkstra ( S, T ) );
#ifdef RYBY
printf ( "calc(%lld,%lld) = (%lld,%lld)\n", a, b, ret.w, ret.e );
#endif
return graph.dijkstra ( S, T );
}
inline void solve ( const Value& A, const Value& B ) {
LL a = A.e - B.e, b = B.w - A.w;
Value C ( calc ( a, b ) );
chkmin ( ans, C.w * C.e );
#ifdef RYBY
printf ( "(%lld,%lld), (%lld,%lld), (%lld,%lld)\n", A.w, A.e, C.w, C.e, B.w, B.e );
printf ( "%lld...%lld\n", ( B - A ) * ( C - A ), a * C.w + b * C.e + A.w * B.e - A.e * B.w );
#endif
if ( ( B - A ) * ( C - A ) >= 0 ) return ;
solve ( A, C ), solve ( C, B );
}
int main () {
n = rint ();
S = ( n - 1 ) * ( n - 1 ) + 1, T = S + 1;
graph.bound = ( n - 1 ) * ( n - 1 ) + 2;
for ( int i = 1; i < n; ++i ) {
for ( int j = 1; j <= n; ++j ) {
int cw = rint (), ce = rint ();
graph ( id ( i, j - 1 ), id ( i, j ), { cw, ce } );
}
}
for ( int i = 1; i <= n; ++i ) {
for ( int j = 1; j < n; ++j ) {
int rw = rint (), re = rint ();
graph ( id ( i - 1, j ), id ( i, j ), { rw, re } );
}
}
Value A ( calc ( 1, 0 ) ), B ( calc ( 0, 1 ) );
chkmin ( ans, A.w * A.e ), chkmin ( ans, B.w * B.e );
solve ( A, B );
printf ( "%lld\n", ans );
return 0;
}
\(\mathcal{Details}\)
虽然套路但毕竟是黑的,一眼秒掉好开心 owo。
Solution -「洛谷 P6158」封锁的更多相关文章
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- Note/Solution -「洛谷 P5158」「模板」多项式快速插值
\(\mathcal{Description}\) Link. 给定 \(n\) 个点 \((x_i,y_i)\),求一个不超过 \(n-1\) 次的多项式 \(f(x)\),使得 \(f(x ...
- Solution -「洛谷 P4198」楼房重建
\(\mathcal{Description}\) Link. 给定点集 \(\{P_n\}\),\(P_i=(i,h_i)\),\(m\) 次修改,每次修改某个 \(h_i\),在每次修改后 ...
- Solution -「洛谷 P6577」「模板」二分图最大权完美匹配
\(\mathcal{Description}\) Link. 给定二分图 \(G=(V=X\cup Y,E)\),\(|X|=|Y|=n\),边 \((u,v)\in E\) 有权 \(w( ...
- Solution -「洛谷 P6021」洪水
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的带点权树,删除 \(u\) 点的代价是该点点权 \(a_u\).\(m\) 次操作: 修改单点点权. ...
- Solution -「洛谷 P4719」「模板」"动态 DP" & 动态树分治
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个结点的带权树,\(m\) 次单点点权修改,求出每次修改后的带权最大独立集. \(n,m\le10^5 ...
- Solution -「洛谷 P5236」「模板」静态仙人掌
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的仙人掌,\(q\) 组询问两点最短路. \(n,q\le10^4\),\(m\ ...
- Solution -「洛谷 P4320」道路相遇
\(\mathcal{Description}\) Link. 给定一个 \(n\) 个点 \(m\) 条边的连通无向图,并给出 \(q\) 个点对 \((u,v)\),询问 \(u\) 到 ...
- Solution -「洛谷 P5827」边双连通图计数
\(\mathcal{Description}\) link. 求包含 \(n\) 个点的边双连通图的个数. \(n\le10^5\). \(\mathcal{Solution}\) ...
随机推荐
- Spark案例练习-UV的统计
关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新)云盘目录说明:tools目录是安装包res 目录是每一个课件对应的代码和资源等doc 目录是一 ...
- 微信小程序动画实现(API,css)
微信小程序动画API实现 index.js clicktap:function(){ var Animation=wx.createAnimation({ duration: 2000, }) Ani ...
- icmpsh之icmp反弹shell
一,技术原理 向ping www.baidu.com时,本机会先向百度的服务器发送ICMP请求包,如果请求成功了,则百度服务器会回应ICMP的响应包 引用百度百科: ICMP(Internet Con ...
- 【C语言】将文本中汉字读入字符数组输出乱码
输出中文字符乱码 今天从文件中将中文读入字符数组后输出发现其中文变成了乱码,,令人头大. 解决办法 将文本编码格式改成ANSI即可. 打开记事本->文件->另存为->更改编码格式-& ...
- 详解__int128
前言 如果遇到 long long 开不下的情况,可以使用 __int128 来博一把! note :__int128 仅 \(64\) 位 \(GCC G++\) 支持,不在 \(C++\) 标准中 ...
- 2022年最新黑苹果monterey安装efi分享
最新版本monterey 12.1 安装. 配置: 名称 型号 备注 主板 Gigabyte Z490M Gaming X 内存 威刚万紫千红DDR4 2666 16G x 2 两条16G 插2 ...
- C++基本面试题1
#include<iostream>using namespace std;class A{public: A(char* s) :name(s), len(strlen(name.c_s ...
- 在Chrome中打开网页时出现以下问题 您的连接不是私密连接 攻击者可能会试图从 x.x.x.x 窃取您的信息(例如:密码、通讯内容或信用卡信息)
现象:在Chrome中打开网页时出现以下问题 您的连接不是私密连接 攻击者可能会试图从 x.x.x.x 窃取您的信息(例如:密码.通讯内容或信用卡信息). 当点开"了解详情"后显示 ...
- mysql加强(6)~子查询简单介绍、子查询分类
一.子查询简单介绍 1.什么是子查询? 一个查询之中嵌套了其他的若干查询. 在使用select 语句查询时,有时候where的查询条件中的限制条件不是一个确定的值,而是一个来自于另一个查询的结果. 子 ...
- TypeScript入门文档
typescript入门文档链接d地址:https://ts.xcatliu.com/basics/type-of-function.html 博主个人站点:www.devloper.top