Codeforces 1045. A. Last chance(網絡流 + 線段樹優化建邊)

題意

給你 \(n\) 個武器,\(m\) 個敵人,問你最多消滅多少個敵人,并輸出方案。

總共有三種武器。

  • SQL 火箭 - 能消滅給你集合中的一個敵人 \(\sum |S| \le 100000\)
  • 認知光束 - 可以消滅 \([l, r]\) 區間中的一個敵人;
  • OMG 火箭筒 - 消滅給你集合中的 \(0\) 個或者 \(2\) 個敵人,集合大小為 \(3\) ,且火箭筒消滅的集合互不重合。

\(n, m \le 5000\)

題解

現場的時候直覺告訴我是網絡流,但是這個數據范圍,以及 CodeForces 從不出網絡流的傳言,不敢剛。。

其實這題還是個網絡流,因為可以看出來還是個是個二分圖求最大匹配的模型(對于前兩種武器來說)。

首先對于第一種武器,可以直接在二分圖上暴力連邊。

第二種武器,我們可以考慮線段樹優化建邊就行了。(就是樹上的邊從父親向兒子連 \(inf\) 就行了)

第三種武器,看起來只有 \(0,2\) 兩種取值很奇怪,其實我們可以把它當成有 \(0,1,2\) 三種取值。

也就是說這個點可以匹配 \(0\sim 2\) 個點。

為什么取 \(1\) 時候是對的呢?因為我們總可以在集合中找另外一個點,把原來消滅它的武器換成這個武器就行了。

然后就可以建完了,至于時間復雜度 ,題解給了一個 \(O(nm \log m)\) 的復雜度,其實我覺得是 \(O(flow)\) 。。


然后輸出方案有些麻煩,首先考慮前兩種武器,第一種武器可以直接先匹配,第二種武器我們在線段樹上自底向上依次分配可行的節點就行了,這個用一個 std :: vector 作為遞歸函數返回值返回值比較好寫。

然后考慮第三種武器,只需要對于 \(flow = 1\) 的情況再找一個匹配了的點,替換消滅的武器就行了。

總結

然后對于一些無法取值的流量,我們可以考慮先取,然后通過構造使得這個流量滿足條件。

網絡流輸出方案的時候考慮退流會退到最開始的哪個地方就行了。

代碼

#include <bits/stdc++.h>#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define debug(x) cout << #x << ": " << (x) << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define All(x) (x).begin(), (x).end()using namespace std;template<typename T> inline bool chkmin(T &a, T b) {return b < a ? a = b, 1 : 0;}
template<typename T> inline bool chkmax(T &a, T b) {return b > a ? a = b, 1 : 0;}inline int read() {int x(0), sgn(1); char ch(getchar());for (; !isdigit(ch); ch = getchar()) if (ch == '-') sgn = -1;for (; isdigit(ch); ch = getchar()) x = (x * 10) + (ch ^ 48);return x * sgn;
}void File() {
#ifdef zjp_shadowfreopen ("a.in", "r", stdin);freopen ("a.out", "w", stdout);
#endif
}int n, m;const int inf = 0x3f3f3f3f;template<int Maxn, int Maxm>
struct Dinic {int Head[Maxn], Next[Maxm], cap[Maxm], to[Maxm], e;Dinic() { e = 1; }inline void add_edge(int u, int v, int flow) {to[++ e] = v; Next[e] = Head[u]; Head[u] = e; cap[e] = flow;}inline void Add(int u, int v, int flow) {add_edge(u, v, flow); add_edge(v, u, 0);}int S, T, dis[Maxn];bool Bfs() {queue<int> Q; Q.push(S); Set(dis, 0); dis[S] = 1;while (!Q.empty()) {int u = Q.front(); Q.pop();for (int i = Head[u], v = to[i]; i; v = to[i = Next[i]])if (cap[i] && !dis[v]) dis[v] = dis[u] + 1, Q.push(v);}return dis[T];}int cur[Maxn];int Dfs(int u, int flow) {if (u == T || !flow) return flow;int res = 0, f;for (int &i = cur[u]; i; i = Next[i]) {int v = to[i];if (dis[v] == dis[u] + 1 && (f = Dfs(v, min(flow, cap[i])))) {cap[i] -= f, cap[i ^ 1] += f, res += f;if (!(flow -= f)) break;}}if (!res) dis[u] = 0;return res;}int Run() {int sum_flow = 0;while (Bfs())Cpy(cur, Head), sum_flow += Dfs(S, inf);return sum_flow;}};const int N = 5050;Dinic<(int)1e5, (int)4e5> D;int tot;#define lson o << 1, l, mid
#define rson o << 1 | 1, mid + 1, r#define Travel(i, u, v) for(int i = D.Head[u], v = D.to[i]; i; v = D.to[i = D.Next[i]])int ans[N], Bef;template<int Maxn>
struct Segment_Tree {int id[Maxn];void Build(int o, int l, int r) {if (l == r) { id[o] = l; return ; }id[o] = ++ tot;int mid = (l + r) >> 1;Build(lson); Build(rson);D.Add(id[o], id[o << 1], id[o << 1] <= m ? 1 : inf);D.Add(id[o], id[o << 1 | 1], id[o << 1 | 1] <= m ? 1 : inf);}inline void Connect(int o, int l, int r, int ql, int qr, int Id) {if (ql <= l && r <= qr) { D.Add(Id, id[o], 1); return ; }int mid = (l + r) >> 1;if (ql <= mid) Connect(lson, ql, qr, Id);if (qr > mid) Connect(rson, ql, qr, Id);}vector<int> find(int o, int l, int r) {if (l == r) return vector<int>();vector<int> tmp;int mid = (l + r) >> 1;vector<int> ls = find(lson), rs = find(rson);set_union(All(ls), All(rs), inserter(tmp, tmp.end()));Travel(i, id[o], v)if (v <= m && !D.cap[i]) tmp.push_back(v);Travel(i, id[o], v) if (D.cap[i] && v > Bef) {int cur = tmp[tmp.size() - 1]; tmp.pop_back();ans[cur] = v - Bef;}return tmp;}};Segment_Tree<N << 2> T;vector<int> V1, V2, V3;int Ref[N], from[N], go[N];void Get_Ans() {for (int u : V1) {Travel(i, Ref[u], v)if (v <= m && D.cap[i ^ 1]) ans[v] = u;}T.find(1, 1, m);for (int u : V3) {int flow = D.cap[from[u]];Travel(i, Ref[u], v)if (v != D.S && !D.cap[i]) ans[v] = u;if (flow == 1)Travel(i, Ref[u], v)if (v != D.S && D.cap[i]) { ans[v] = u; break; }}
}int main () {File();n = read(), m = read();tot = m; T.Build(1, 1, m); Bef = tot;D.S = tot + n + 1; D.T = tot + n + 2;For (i, 1, m) D.Add(i, D.T, 1), go[i] = D.e - 1;For (i, 1, n) {int opt = read();D.Add(D.S, Ref[i] = ++ tot, 1 + (opt == 2)); from[i] = D.e - 1;if (opt == 0) {int k = read(); V1.push_back(i);while (k --) D.Add(tot, read(), 1);} else if (opt == 1) {int l = read(), r = read(); V1.push_back(i);T.Connect(1, 1, m, l, r, tot);} else {int a = read(), b = read(), c = read();V3.push_back(i);D.Add(tot, a, 1);D.Add(tot, b, 1);D.Add(tot, c, 1);}}printf ("%d\n", D.Run());Get_Ans();For (i, 1, m) if (ans[i])printf ("%d %d\n", ans[i], i);return 0;}

轉載于:https://www.cnblogs.com/zjp-shadow/p/9700362.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/451196.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/451196.shtml
英文地址,請注明出處:http://en.pswp.cn/news/451196.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

常用宏定義 - 系統相關

/** 是否iPad */ #define isPad (UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPad)/** 是否iPad */ #define someThing (UI_USER_INTERFACE_IDIOM() UIUserInterfaceIdiomPad)? ipad: iphone/** 獲取系統版本 */ #define IOS_VERSION &#xff3b;[UIDevice currentDevi…

周鴻祎詳解360手機戰略:賺錢不靠硬件靠服務

摘要&#xff1a;奇虎360總裁周鴻祎不久前在微博上宣布360公司將要進軍手機行業的消息后&#xff0c;一度掀起業界的軒然大波&#xff0c;褒貶之聲均不絕于耳。對于合作廠商的選擇&#xff0c;周鴻祎直言出貨量是一個重要參考指標&#xff0c;“每年的出貨量最少不低于500萬~10…

解決報錯:;Syntax error on token(s), misplaced construct(s)

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 報錯如題&#xff0c;這是語法錯誤&#xff0c;如括號不匹配、代碼沒有寫在一個方法中、少分號、變量名不對、少半個大括號 ... 總之就…

java移位運算符

java中有三種移位運算符 << : 左移運算符&#xff0c;num << 1 相當于num乘以2 >> : 右移運算符&#xff0c;num >> 1 相當于num除以2 >>> : 無符號右移&#xff0c;忽略符號位&#xff0c;空位都以0補齊…

在頁面上顯示PDF

/// <summary>/// 讀取PDF文件/// </summary>/// <param name"fName">文件名稱(可以從其他地方傳進來)</param>/// <returns></returns>public FileStreamResult readPDF(string fName "pdf文件.pdf"){string dirp …

7.15模擬賽

T1.fuction 吐槽一波錯誤拼寫。 跟考場思路差不多&#xff0c;只不過細節挺多的呢。 判掉a0,b0,c0的幾種組合&#xff0c;還有負數的情況要打標記特殊處理。 然后就是一個拓歐啦&#xff0c;先求出ggcd(a,b)&#xff0c;順便求出axbyg的x和y&#xff0c;然后根據裴蜀定理&#…

蘇寧國美盈利報警:線下乏力線上重金加碼

摘要&#xff1a;國美電器則發布盈利預警&#xff0c;預計今年一季度凈利潤同比大幅減少———這也致使國美股價最近連續低位徘徊。蘇寧電器一季報顯示&#xff0c;今年1至3月公司營業收入226 .41億元&#xff0c;同比增長10%&#xff0c;但盈利9.51億元&#xff0c;同比下降15…

WebService到底是什么?

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、序言 大家或多或少都聽過WebService&#xff08;Web服務&#xff09;&#xff0c;有一段時間很多計算機期刊、書籍和網站都大肆的提…

JAVA中PO,VO,DTO,BO,DAO,POJO解釋

&#xff08;一&#xff09;VO與PO ORM是Object Relational Mapping&#xff08;對象關系映射&#xff09;的縮寫。通俗點講&#xff0c;就是將對象與關系數據庫綁定&#xff0c;用對象來表示關系數據。在O/R Mapping的世界里&#xff0c;有兩個基本的也是重要的東東需要了解&…

互掐盜播風云再起 三大視頻網站存和解可能

摘要&#xff1a;近期&#xff0c;視頻網站互掐盜播風云再起。騰訊視頻已于5月13日向PPS開炮&#xff0c;宣稱PPS盜播其五部獨家劇&#xff1b;5月14日&#xff0c;搜狐視頻亦指責PPS盜播其23部熱播劇。面對這兩家的連續開炮&#xff0c;PPS方面也進行了相應的回應&#xff0c;…

springboot和quartz整合實現動態定時任務(持久化單節點)

Quartz是一個完全由java編寫的開源作業調度框架,為在Java應用程序中進行作業調度提供了簡單卻強大的機制&#xff0c;它支持定時任務持久化到數據庫&#xff0c;從而避免了重啟服務器時任務丟失&#xff0c;支持分布式多節點&#xff0c;大大的提高了單節點定時任務的容錯性。s…

JAVA中protected的作用

類NewObject中有protected修飾的方法或者屬性&#xff0c;則&#xff1a; 同一個包中&#xff1a; 可在同一個包里的子類中實例化NewObject類獲得對象&#xff0c;然后可用該對象訪問protected修飾的方法或者屬性&#xff0c;即.操作訪問。可在同一個包里的非子類中實例化NewOb…

wsimport 不是內部或外部命令,也不是可運行的程序或批處理文件

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 今天使用wsimport生成webservice client端代碼&#xff0c;wsimport提示不是內部或外部命令&#xff0c;也不是可運行的程序或批處理文件…

靜態變量的多線程同步問題

2019獨角獸企業重金招聘Python工程師標準>>> 我們先來討論一個問題&#xff0c;一個類的靜態變量當類被多次實例化的時候&#xff0c;靜態變量是否會受影響&#xff1f;首先我們應該清楚的是靜態變量是在類被JVM classloader的時候分配內存&#xff0c;并且是分配在…

extends和implements區別

extends和implements區別 extends與implements的不同 1、在類的聲明中&#xff0c;通過關鍵字extends來創建一個類的子類。 一個類通過關鍵字implements聲明自己使用一個或者多個接口。 extends 是繼承某個類, 繼承之后可以使用父類的方法, 也可以重寫父類的方法; imple…

評論:電商巨頭們誰有勇氣曬曬“價格戰”賬單?

摘要&#xff1a;國內電商接二連三上演的“價格戰”&#xff0c;點燃了消費者的購買熱情。在筆者看來&#xff0c;如果有哪個大型電商有勇氣亮出價格戰賬單&#xff0c;那對競爭對手的刺激和打擊效果將非同一般。曬出了賬單后&#xff0c;消費者對購物場所的選擇也將一目了然&a…

The xxx collides with a package/type

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 當類和包&#xff0c;重名時&#xff0c;包會報錯誤&#xff1a;The package aaa.a collides with a type&#xff1b;類也會報警告&…

Hive 行列轉換

在京東眾多業務中&#xff0c;促銷業務充滿了復雜性和挑戰性&#xff0c;因為業務的靈活性&#xff0c;很多數據都存儲成xml和json格式數據&#xff0c;這就要求下游數據分析師們需要對其做解析后方可使用 。 在眾多操作中 &#xff0c;有一種是需要對數據做行列轉換操作。 數據…

[譯] 論 Rust 和 WebAssembly 對源碼地址索引的極限優化

原文地址&#xff1a;Oxidizing Source Maps with Rust and WebAssembly原文作者&#xff1a;Nick Fitzgerald譯文出自&#xff1a;掘金翻譯計劃本文永久鏈接&#xff1a;github.com/xitu/gold-m…譯者&#xff1a;D-kylinTom Tromey 和我嘗試使用 Rust 語言進行編碼&#xff0…

Java WebService 簡單實例

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 前言&#xff1a;朋友們開始以下教程前&#xff0c;請先看第五大點的注意事項&#xff0c;以避免不必要的重復操作。 一、準備工作&…