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}\) ...
随机推荐
- Jsp页面中常见的page指令
注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6513327323628962312/ 1.<JSP页面实际上就是Servlet> 2.<JSP页 ...
- 老旧业务重构案例——IM系统如何设计
一年半之前刚来到这个团队,便遭遇了一次挑战: 当时有个CRM系统,老是出问题,之前大的优化进行了4次小的优化进行了10多次,要么BUG重复出现,要么性能十分拉胯,总之体验是否糟糕!技术团队因此受到了诸 ...
- MySQL注入点写webshell的五种方式
0x00 写数据的前提 1,在mysql的配置文件 my.ini 中,secure_file_priv="c:/wamp64/tmp" 被注释 或者 `secure_file_pr ...
- java集合对比汇总
List.Set和Map: List是有序的集合,Set是无序的集合.Map是无序的键值对. HashMap详解: HashMap有两个参数影响其性能:初始容量和加载因子.默认初始容量是16,加载因子 ...
- 【Android】安卓开发中的布局与事件
[Android]安卓开发中的布局与事件 1.Android Studio下载配置 非常简单的百度然后点击下载安装就好了.注意的是,本来我是打算使用评价还不错的Genymotion这个软件来充当虚拟机 ...
- IPV4地址,子网掩码,子网划分
转载自https://blog.csdn.net/qq_45108415/article/details/114179407
- linux中sort命令全面解析
目录 一:sort命令作用 二:sort格式 1.sort参数 2.参数解析 sort命令简介 Linux sort 命令用于将文本文件内容加以排序. sort 可针对文本文件的内容,以行为单位来排序 ...
- linux虚拟机快照
目录 一:虚拟机快照 一:虚拟机快照 1.什么是快照? 快照可保存虚拟机在特定时刻的状态和数据. 状态包括虚拟机的电源状态(列如,打开电源,关闭电源,挂起). 数据包括组成虚拟机的所有文件,这包括磁盘 ...
- 沁恒CH32F103C8T6(二): Linux PlatformIO环境配置, 示例运行和烧录
目录 沁恒CH32F103C8T6(一): Keil5环境配置,示例运行和烧录 沁恒CH32F103C8T6(二): Linux PlatformIO环境配置, 示例运行和烧录 StdPeriphLi ...
- SpringMVC之RedirectAttributes属性
RedirectAttributes是SpringMVC3.1版本之后出来的一个新功能,专门用于重定向之后还能带参数跳转的的工具类. 两种带参方式: redirectAttributes.addAtt ...