POJ - 2226 Muddy Fields(最小点覆盖-二分图最大匹配)
生活随笔
收集整理的這篇文章主要介紹了
POJ - 2226 Muddy Fields(最小点覆盖-二分图最大匹配)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一個n*m的地圖,地圖中‘*’代表泥地,‘.’代表空地,現在我們有兩種木板,一種可以覆蓋一行中的任意長度,我們成為行木板,另一種可以覆蓋一列中的任意長度,我們成為列木板,但這兩種木板都不能覆蓋空地,現在要求用最少的木板覆蓋所有泥地
題目分析:因為每一個方格都有兩種方案被覆蓋,即一種是被行木板覆蓋,一種是被行木板所覆蓋,一種是被列木板所覆蓋,這樣一來我們就可以將行木板劃分為一個集合,列木板劃分為另一個集合,然后就變成二分圖的匹配問題了,具體該怎么匹配呢,對于每一個點(x,y),我們將該點所對應的行木板和列木板建邊,因為我們要用最少的邊覆蓋掉所有的頂點,這樣問題就轉換成了最小點覆蓋的問題了,最小點覆蓋=二分圖最大匹配,跑一遍匈牙利答案就出來了
這個題的難點我感覺還是在建邊上,只要邊建好了剩下的就是模板題了,這里我是用while來建邊的,感覺不是想象中的那么困難
還有一個細節,就是行泥濘塊和列泥濘塊大概最多能有N*N/2個,如果按照常規的匈牙利時間復雜度是n*n的,每一次的時間復雜度大概到了1e6,如果怕這個題目會故意卡時間,可以選擇用鄰接表存邊,這樣時間復雜度就下降到了n*m了
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=55;char s[N][N];int num1[N][N],num2[N][N];int r[N*N],c[N*N];int cnt1,cnt2;vector<int>node[N*N];bool vis[N*N];int match[N*N];bool dfs(int x) {for(int i=0;i<node[x].size();i++){int y=node[x][i];if(!vis[y]){vis[y]=true;if(!match[y]||dfs(match[y])){match[y]=x;return true;}}}return false; }void init() {for(int i=0;i<N*N;i++)node[i].clear();cnt1=cnt2=0;memset(match,0,sizeof(match));memset(num1,0,sizeof(num1));memset(num2,0,sizeof(num2)); }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int n,m;while(scanf("%d%d",&n,&m)!=EOF){init();for(int i=0;i<n;i++)scanf("%s",s[i]);for(int i=0;i<n;i++)//行泥濘塊 for(int j=0;j<m;j++){if(s[i][j]=='*'){num1[i][j]=++cnt1;while(j+1<m&&s[i][j]=='*'&&s[i][j]==s[i][j+1]){num1[i][j+1]=cnt1;j++;}}}for(int j=0;j<m;j++)//列泥濘塊 for(int i=0;i<n;i++){if(s[i][j]=='*'){num2[i][j]=++cnt2;while(i+1<n&&s[i][j]=='*'&&s[i][j]==s[i+1][j]){num2[i+1][j]=cnt2;i++;}}}for(int i=0;i<n;i++)//建邊for(int j=0;j<m;j++)if(s[i][j]=='*')node[num1[i][j]].push_back(num2[i][j]);int ans=0;for(int i=1;i<=cnt1;i++){memset(vis,false,sizeof(vis));if(dfs(i))ans++;}printf("%d\n",ans);}return 0; }?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的POJ - 2226 Muddy Fields(最小点覆盖-二分图最大匹配)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 3565 Ants(二分图最
- 下一篇: CH - 4901 关押罪犯(二分图判定