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}\) ...
随机推荐
- Oracle - 以 INSERT SQL语句形式导出结果集
使用 SQLcl - 这是 SQL Developer 的命令行接口 下载 SQLcl sql sys/welcome@localhost:1521:orcl as sysdba #sql usern ...
- Ant <Delete> 如何只删掉文件夹下所有文件和文件夹
用 fileset 来过滤要删掉的目录和文件 <project name="ant-project" default="example"> < ...
- [转]webpack配置本地服务器
亲测,webpack打包vue项目之后生成的dist文件可以部署到 express 服务器上运行. 我的vue项目结构如下: 1. 进入该vue项目目录,打开git bash,执行:npm run b ...
- Guava Cache源码浅析
1. 简介 Guava Cache是指在JVM的内存中缓存数据,相比较于传统的数据库或redis存储,访问内存中的数据会更加高效,无网络开销. 根据Guava官网介绍,下面的这几种情况可以考虑使用Gu ...
- 关于在Vue中使用WebScoket的随笔
声明:请勿直接复制粘贴抄袭文章,若有需要,请规范转载,注明出处,谢谢! ---------------------------------------------------------------- ...
- idea同时启动多个微服务模块进行管理
1,打开IDEA项目中的 .idea 下 的workspace.xml 找到文件中的 RunDashboard 配置块,增加如下圈起来的地方 代码: <option name="con ...
- Genymotion模拟器配置与使用
1.https://www.genymotion.com网站注册模拟器账号,并按照指引激活账号 此过程中提示商业用还是个人使用,商业使用需要有注册码,个人使用不需要注册码,我选择的是个人使用. 2.激 ...
- Sentry 开发者贡献指南 - 测试技巧
作为 CI 流程的一部分,我们在 Sentry 运行了多种测试. 本节旨在记录一些 sentry 特定的帮助程序, 并提供有关在构建新功能时应考虑包括哪些类型的测试的指南. 获取设置 验收和 pyth ...
- QT之键盘事件
Widget.h: #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<QKeyEvent> #incl ...
- 使用AJAX请求调用出现HTTPS协议错误问题
前言: 这又是一个可能是半路就卡机的项目,在调用ajax的时候遇到了下面的这个错. js中有个ajax请求http,url是:http//:.js就提示请求了一个不安全的脚本,在发送ajax请求时,就 ...