日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces 1517G Starry Night Camping(网络流最小割)

發布時間:2023/12/3 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces 1517G Starry Night Camping(网络流最小割) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

CodeForces 1517G Starry Night Camping

problem

洛谷鏈接

solution

這個平行四邊形的腦洞我?真的長見識了

本題最離譜的要求就是:平行四邊形的一條邊平行于 xxx

而往往這種離譜要求就是正解的途徑。(((φ(◎ロ◎;)φ)))

首先不觀察也能知道,中心點的上下必須選一個,左右必須選一個,這樣就確定了三個點。

最后一個點在上下和左右選出來后也就有了選擇限制。

這個選擇限制就是不能讓選的左右點與中心點的邊成為對角線(這種斜著的平行四邊形是被允許存在的)。

再看,還要求中心點的坐標都是偶數,我們用 O 表示奇數,E 表示偶數。

那么中心點就是 (E,E),左右點都是 (E,O),上下點都是 (O,E),剩下的一個點都是 (O,O)。

換言之,平行四邊形的四個頂點一定是由上面四類各出一個點構成的。

我們用路徑來刻畫平行四邊形的邊。

發現不合法的平行四邊形都可以被表示為 (O,O)→(O,E)→(E,E)→(E,O)(O,O)\rightarrow(O,E)\rightarrow (E,E)\rightarrow (E,O)(O,O)(O,E)(E,E)(E,O),一條邊連接的兩個點的距離恰好為 111

這說明,如果將點按橫縱坐標分成四大類,最后是不能出現長度為 444 的鏈的。

而這四類之間的邊是唯一的,定向的。

可以用拆點+網絡流。把一個坐標點拆成入點和出點,再建一個超級源點和超級匯點。

入點和出點之間就是坐標點的刪除代價,其余邊容量無窮即可。

最后是不能讓 S?TS-TS?T 之間存在流量的,也就是要把 S/TS/TS/T 割開,即最小割問題

code

#include <bits/stdc++.h> using namespace std; #define inf 1e18 #define int long long #define maxn 2005 queue < int > q; int s, t, cnt = -1; int dep[maxn], head[maxn], cur[maxn]; struct node { int to, nxt, flow; }E[maxn << 4];void addedge( int u, int v, int w ) {E[++ cnt] = { v, head[u], w };head[u] = cnt;E[++ cnt] = { u, head[v], 0 };head[v] = cnt; }bool bfs() {memset( dep, 0, sizeof( dep ) );memcpy( cur, head, sizeof( head ) );q.push( s ), dep[s] = 1;while( ! q.empty() ) {int u = q.front(); q.pop();for( int i = head[u];~ i;i = E[i].nxt ) {int v = E[i].to;if( ! dep[v] and E[i].flow > 0 ) {dep[v] = dep[u] + 1;q.push( v );}}}return dep[t]; }int dfs( int u, int cap ) {if( ! cap or u == t ) return cap;int flow = 0;for( int i = cur[u];~ i;i = E[i].nxt ) {cur[u] = i; int v = E[i].to;if( dep[v] == dep[u] + 1 and E[i].flow > 0 ) {int w = dfs( v, min( cap, E[i].flow ) );E[i ^ 1].flow += w;E[i].flow -= w;flow += w;cap -= w;if( ! cap ) break;}}return flow; }int dinic() {int ans = 0;while( bfs() ) ans += dfs( s, inf );return ans; }int n; int x[maxn], y[maxn], w[maxn], type[maxn];signed main() {memset( head, -1, sizeof( head ) );scanf( "%lld", &n );int ans = 0;s = 1, t = n + 1 << 1;for( int i = 1;i <= n;i ++ ) {scanf( "%lld %lld %lld", &x[i], &y[i], &w[i] );if( (x[i] & 1) and (y[i] & 1) ) type[i] = 1;if( (x[i] & 1) and !(y[i] & 1) ) type[i] = 2;if( !(x[i] & 1) and !(y[i] & 1) ) type[i] = 3;if( !(x[i] & 1) and (y[i] & 1) ) type[i] = 4;ans += w[i];}for( int i = 1;i <= n;i ++ ) addedge( i << 1, i << 1 | 1, w[i] );for( int i = 1;i <= n;i ++ ) if( type[i] == 1 ) addedge( s, i << 1, inf );for( int k = 1;k <= 3;k ++ )for( int i = 1;i <= n;i ++ )if( type[i] == k )for( int j = 1;j <= n;j ++ )if( type[j] == k + 1 )if( fabs( x[i] - x[j] ) + fabs( y[i] - y[j] ) == 1 )addedge( i << 1 | 1, j << 1, inf );for( int i = 1;i <= n;i ++ ) if( type[i] == 4 ) addedge( i << 1 | 1, t, inf );printf( "%lld\n", ans - dinic() );return 0; }

總結

以上是生活随笔為你收集整理的CodeForces 1517G Starry Night Camping(网络流最小割)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。