[Hnoi2013]消毒

Description

最近在生物實驗室工作的小T遇到了大麻煩。
由于實驗室最近升級的緣故,他的分格實驗皿是一個長方體,其尺寸為abc,a、b、c 均為正整數。為了實驗的方便,它被劃分為abc個單位立方體區域,每個單位立方體尺寸
為111。用(i,j,k)標識一個單位立方體,1 ≤i≤a,1≤j≤b,1≤k≤c。這個實驗皿已經很久沒有人用了,現在,小T被導師要求將其中一些單位立方體區域進 行消毒操作(每個區域可以被重復消毒)。而由于嚴格的實驗要求,他被要求使用一種特定 的F試劑來進行消毒。 這種F試劑特別奇怪,每次對尺寸為xyz的長方體區域(它由xyz個單位立方體組 成)進行消毒時,只需要使用min{x,y,z}單位的F試劑。F試劑的價格不菲,這可難倒了小 T。現在請你告訴他,最少要用多少單位的F試劑。(注:min{x,y,z}表示x、y、z中的最小 者。)

Input

第一行是一個正整數D,表示數據組數。接下來是D組數據,每組數據開頭是三個數a,b,c表示實驗皿的尺寸。接下來會出現a個b 行c列的用空格隔開的01矩陣,0表示對應的單位立方體不要求消毒,1表示對應的單位立方體需要消毒;例如,如果第1個01矩陣的第2行第3列為1,則表示單位立方體(1,2,3)需要被消毒。輸入保證滿足abc≤5000,T≤3。

Output

僅包含D行,每行一個整數,表示對應實驗皿最少要用多少單位 的F試劑。

Sample Input

1
4 4 4
1 0 1 1
0 0 1 1
0 0 0 0
0 0 0 0
0 0 1 1
1 0 1 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 0 0 0

Sample Output

3

HINT

對于區域(1,1,3)-(2,2,4)和(1,1,1)-(4,4,1)消毒,分別花費2個單位和1個單位的F試劑。2017.5.26新加兩組數據By Leoly,未重測.

Solution

洛谷的評測機有偉大的神力。。。。

對于這個題,有一種鬼畜的偽證,至于是什么不想說了。。。

首先我們可以證明我們一次一定是要消掉一個面的,也就是消除的部分中的{x,y,z}里面一定有一個是1,其他兩個撐到最大,因為這樣可以保證最優。

那么我們現在可以繼續看這道題了。首先考慮這樣一個算法,假設這個題目的要求變成在一個二維平面上搞,那么明顯,我們把每行每列當做點,把格子里是否有數變成邊,不難看出我們現在就是要求這個題的最小覆蓋集,那么沒的說了,一個最大流隨便就過了。

然后我們開始考慮三維的,明顯的是,沒有三分圖匹配這種鬼畜的算法,那么怎么辦呢?

題目中有這樣一個條件,\(a\times b\times c\le 5000\)。隨便開一下根可以發現,這仨數里面肯定有一個比17要小,那么就可以搞搞事情了,我們可以把這個立方體最小的那條邊當成高,然后枚舉刪掉哪一層,把沒有刪去的層拍扁到一個二維平面上,那么就可以在這個新的二維平面上搞搞二分圖匹配什么的了。

那么我們是不是就輕松A掉了這個題?

Code1

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <set>
#define re register
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define pos(i,j,l) ((i-1)*b*c+(j-1)*c+l)
#define MAXN 5005
#define MAXM 15011
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(arr) memset(arr, 0, sizeof(arr))
const int inf = 0x3f3f3f3f;
int n,s,t,cur[MAXN],m;
int d[5005],cut[20],a,b,c,cost,minn=100,cnt;
int sx[4][5005];
struct po
{int nxt,to,w;
}edge[MAXM];
int head[MAXN],dep[MAXN],num=-1;
inline int read()
{int x=0,c=1;char ch=' ';while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();while(ch=='-') c*=-1,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=getchar();return x*c;
}
inline void add_edge(int from,int to,int w)
{edge[++num].nxt=head[from];edge[num].to=to;edge[num].w=w;head[from]=num;
}
inline void add(int from,int to,int w)
{add_edge(from,to,w);add_edge(to,from,0);
}
inline bool bfs()
{for(re int i=s;i<=t;i++)dep[i]=0;queue<int> q;while(!q.empty())q.pop();q.push(s);dep[s]=1;while(!q.empty()){int u=q.front();q.pop();for(re int i=head[u];i!=-1;i=edge[i].nxt){int v=edge[i].to;if(dep[v]==0&&edge[i].w>0){dep[v]=dep[u]+1;if(v==t) return 1;q.push(v);}}}return 0;
}
inline int dfs(int u,int dis)
{if(u==t)return dis;int diss=0;for(re int& i=cur[u];i!=-1;i=edge[i].nxt){int v=edge[i].to;if(edge[i].w!=0&&dep[v]==dep[u]+1){int check=dfs(v,min(dis,edge[i].w));if(check!=0){dis-=check;diss+=check;edge[i].w-=check;edge[i^1].w+=check;if(dis==0) break;}}}return diss;
}
inline int dinic()
{int ans=0;while(bfs()){for(re int i=0;i<=t;i++)cur[i]=head[i];while(int d=dfs(s,inf))ans+=d;}return ans;
}
inline void get_cut(int x)
{memset(cut,0,sizeof(cut));for(re int i=0;i<a;i++){if(x&(1<<i)) cut[i+1]=1,cost++;}
}
inline void build()
{for(re int i=1;i<=b;i++)add(s,i,1);for(re int i=1;i<=c;i++)add(i+b,t,1);
}
inline void prepare()
{for(re int i=s;i<=t;i++) head[i]=-1;num=-1;
}
inline void copy()
{for(re int i=1;i<=cnt;i++)if(!cut[sx[1][i]])add(sx[2][i],sx[3][i]+b,1);
}
int main()
{int T=read();while(T--){a=read();b=read();c=read();int minx=min(a,min(b,c));memset(sx,0,sizeof(sx));cnt=0;for(re int i=1;i<=a;i++)for(re int j=1;j<=b;j++)for(re int l=1;l<=c;l++){int x=read();if(!x) continue;sx[1][++cnt]=i;sx[2][cnt]=j;sx[3][cnt]=l;}if(minx==b) swap(a,b),swap(sx[1],sx[2]);else if(minx==c) swap(a,c),swap(sx[1],sx[3]);s=0,t=b+c+1;for(re int i=0;i<1<<a;i++){cost=0;get_cut(i);if(cost>minn) continue;prepare();copy();build();cost+=dinic();minn=min(minn,cost);}cout<<minn<<endl;minn=100;}
}

But

看到這個Code不同尋常了吧,這個代碼在洛谷上開著O2A掉了,然后令人驚奇的是,它過不了我自己手造的隨機數據。。然后我把gay的比我快10倍的代碼拿過來測了測,照樣過不了。。。。然后發現把圖拍扁的時候這個效率有可能退化為\(a*b*c\)的鬼畜效率,光這個就T掉了。。。。然后。。。看了下題解第一個,發現是一遍DFS一遍重新構造圖。。然后,沒有然后了。

Code2

額,題解代碼,我自己的改來改去太丑了,仔細看看那個搜索過程,

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
inline int read() {int res = 0; bool bo = 0; char c;while (((c = getchar()) < '0' || c > '9') && c != '-');if (c == '-') bo = 1; else res = c - 48;while ((c = getchar()) >= '0' && c <= '9')res = (res << 3) + (res << 1) + (c - 48);return bo ? ~res + 1 : res;
}
const int N = 5005, E = 23, INF = 0x3f3f3f3f;
int n, D[5], pos, ecnt, nxt[N], adj[N], go[N], val[N], my[N],
X[N][5], Ans, cnt, vis[N], times;
bool sel[E];
void add_edge(int u, int v, int w) {nxt[++ecnt] = adj[u]; adj[u] = ecnt; go[ecnt] = v; val[ecnt] = w;
}
bool dfs(int u) {for (int e = adj[u], v; e; e = nxt[e])if (!sel[val[e]] && vis[v = go[e]] < times) {vis[v] = times;if (!my[v] || dfs(my[v])) {my[v] = u;return 1;}}return 0;
}
int solve(int tt) {int i, j, ans = 0;for (i = 1; i <= cnt; i++) my[i] = 0;for (i = 1; i <= cnt; i++) {times++;if (dfs(i)) ans++;if (tt + ans >= Ans) return tt + ans;}return tt + ans;
}
void Dfs(int dep, int tt) {if (dep > D[pos]) return (void) (Ans = min(Ans, solve(tt)));sel[dep] = 1; Dfs(dep + 1, tt + 1);sel[dep] = 0; Dfs(dep + 1, tt);
}
void work() {int i, j, k, x; n = 0; Ans = INF; cnt = 0;pos = 1; D[1] = read(); D[2] = read(); D[3] = read();if (D[2] < D[pos]) pos = 2; if (D[3] < D[pos]) pos = 3;for (i = 1; i <= 3; i++) if (i != pos) cnt = max(cnt, D[i]);for (i = 1; i <= D[1]; i++) for (j = 1; j <= D[2]; j++)for (k = 1; k <= D[3]; k++) {x = read(); if (x) X[++n][1] = i, X[n][2] = j, X[n][3] = k;}ecnt = 0; for (i = 1; i <= cnt; i++) adj[i] = 0;for (i = 1; i <= n; i++) {if (pos == 1) add_edge(X[i][2], X[i][3], X[i][1]);else if (pos == 2) add_edge(X[i][1], X[i][3], X[i][2]);else add_edge(X[i][1], X[i][2], X[i][3]);}printf("%d\n", (Dfs(1, 0), Ans));
}
int main() {int T = read();while (T--) work();return 0;
}

轉載于:https://www.cnblogs.com/victorique/p/9042473.html

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

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

相關文章

php按照文件名字排序,php readdir 排序問題,如何按照日期進行排序

目前是這么寫的&#xff1a;function posts_get($directory,$ext){if (is_dir($directory)) {$handle opendir($directory);while ($file readdir($handle)){$subdir $directory . / .$file;if ($file ! . && $file !.. && is_dir($subdir)){posts_get($sub…

關系模型的名詞

關系&#xff08;Relation&#xff09;一個關系對應通常說的一張表元組&#xff08;Tuple&#xff09;表中的一行即為一個元組屬性&#xff08;Attribute&#xff09;表中的一列即為一個屬性&#xff0c;給每一個屬性起一個名稱即屬性名主碼&#xff08;Key&#xff09;也稱碼鍵…

物理卷、卷組、邏輯卷

參考文章&#xff1a; 相關文獻 謝謝作者分享!

fibonacci數列的題目——劍指Offer

https://www.nowcoder.net/practice/c6c7742f5ba7442aada113136ddea0c3?tpId13&tqId11160&tPage1&rp1&ru/ta/coding-interviews&qru/ta/coding-interviews/question-ranking 大家都知道斐波那契數列&#xff0c;現在要求輸入一個整數n&#xff0c;請你輸出…

如何高效的編寫與同步博客 (.NET Core 小工具實現)

系列目錄 [如何高效的編寫與同步博客&#xff08;一&#xff09;- 編寫 ]如何高效的編寫與同步博客&#xff08;二&#xff09;- 快速發布到多個渠道一.前言 寫博客&#xff0c;可以帶給我們很多好處&#xff0c;比如可以讓我們結識更多志同道合的人&#xff1b;在寫博客過程中…

java appendable,org.eclipse.jetty.util.Utf8Appendable$NotUtf8Exception: Not valid UTF8

上傳文件奇怪的錯誤2016-10-14 11:00:52,254 nuoshang.bluejay.common.shiro.cache.RedisCache.put(RedisCache.java:54) DEBUG - SET nameshiro-activeSessionCache key70qv5bejsihmgot7hroqg6q0lv2016-10-14 11:00:52,254 nuoshang.bluejay.common.shiro.cache.LCache.fire(L…

Oracle高可用概述(HA與RAC的關系解惑)

1.你如何理解高可用的概念&#xff1f; 所謂的高可用HA就是當你的系統中的某個節點異常損壞了&#xff0c;系統還是可用狀態&#xff0c;還可以對外提供服務&#xff0c;不會因為你的節點丟失而整體癱瘓。 2.列出你知道的Oracle高可用產品&#xff0c;并作一些功能和應用場景上…

從github clone文件: Failed to receive SOCKS4 connect request ack.

安裝了代理&#xff0c;能上網&#xff0c;也能從github上下載文件&#xff0c;就是無法從github上clone文件&#xff0c; 查了很久資料后&#xff0c;終于發現使用sudo可以解決問題。不過&#xff0c;不知道原因是什么&#xff1f; 比如&#xff1a;git clone https://github.…

mxf高速發展和數字電影母版制作技術

1.實現MXF的諾言——格式只是邁向可互操作內容管理的一步 當把元數據加到數字內容的MXF&#xff08;素材交換格式&#xff09;標準通過EBU于2002年推出時&#xff0c;當時曾預期廣播機構將會迅速無縫地管理其所有來自不同廠家的制作、后期和分配系統上的數字內容。 六年過…

Android 路由實踐(二)

前言繼上一篇Android 路由實踐&#xff08;一&#xff09;之后&#xff0c;斷更已經差不多一個月&#xff0c;畢竟是年前的最后一個月&#xff0c;各種事情扎堆&#xff0c;直到近幾天才稍微閑下來&#xff0c;于是有了此文。簡單回顧下&#xff0c;上一篇文章中簡單介紹了三種…

php中newself(),在php代碼中新建對象用到的new self與new static有什么不同

我們在使用php代碼新建對象的時候&#xff0c;一般會用到new self與new static,那么它們在使用的時候區別在哪里&#xff1f;先說說new static(),new static與new self一樣&#xff0c;在php代碼中&#xff0c;它是用來新建一個對象的.那么他們之間的不同之處在哪里呢&#xff…

ORACLE rac集群概念和原理

參考文獻&#xff1a; 文獻一 文獻二 文獻三 謝謝作者分享&#xff01;

Python基礎-變量作用域

1.函數作用域介紹 函數作用域 Python中函數作用域分為4種情況&#xff1a; L&#xff1a;local&#xff0c;局部作用域&#xff0c;即函數中定義的變量&#xff1a;E&#xff1a;enclosing&#xff0c;嵌套的父級函數的局部作用域&#xff0c;即包含此函數的上級函數的局部作用…

視頻源常見接口介紹

在錄制和播放中&#xff0c;要通過接口實現文件的傳輸&#xff0c;下面介紹常用接口。 [AV IN/OUT/PHONES]&#xff1a;這是一個多功能的插孔&#xff0c;在菜單里可以設置其功能。當設置為[IN/OUT]時&#xff0c;此插孔可以輸入和輸出音頻以及視頻信號&#xff0c;用于連接電視…

php愛奇藝篩選標簽,三種排序 快速篩選好視頻_軟件資訊技巧應用-中關村在線

使用在線視頻播放器來觀看視頻&#xff0c;通常有可以分為有目標和無目標兩種。即是用戶如果定點找一部視頻和隨意查看喜歡的視頻&#xff0c;這兩種模式往往查找視頻的方法也是不一樣的。我們這里要和大家講解的是&#xff0c;用戶在沒有目標視頻的情況下&#xff0c;怎樣更快…

TSAP傳輸服務訪問點

TSAP(Transport Service Access Point) 傳輸服務訪問點在計算機網絡當中&#xff0c;傳輸層要在用戶之間提供可靠和有效的端-端&#xff08;如TSAP源端->[1]TSAP目的端的傳輸選擇&#xff09;服務&#xff0c;必須把一個用戶進程和其他的用戶進程區分開&#xff0c;主要由傳…

Flask項目--發送短信驗證碼

1.后端代碼 具體代碼如下&#xff1a; # GET /api/v1.0/sms_codes/<mobile>?image_codexxxx&image_code_idxxxx api.route("/sms_codes/<re(r1[34578]\d{9}):mobile>") def get_sms_code(mobile):"""獲取短信驗證碼""&q…

Jenkins系列之五——通過Publish over SSH插件實現遠程部署

Jenkins通過Publish over SSH插件實現遠程部署 步湊一、配置ssh免秘鑰登錄 部署詳情地址&#xff1a;http://www.cnblogs.com/Dev0ps/p/8259099.html 步湊二、安裝Publish over SSH插件 插…