C - Asteroids POJ - 3041

匈牙利算法
題目描述:你的飛船有個強大的武器可以打小行星,一次可以攻擊一行或者一列,求最少的攻擊次數。
題目分析:問題可以轉化爲,選取最少的點,使得這些點與所有的邊相鄰。把方陣看做一個二分圖,v1作爲行頂點集,v2作爲列頂點集,那x,y可以看做點,圖中的點graph[x][y]則可以看做一條邊,問題就是最小點覆蓋數問題=最大匹配數,用匈牙利算法。

代碼如下:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int maxn=500+10;
int v1,v2;
int graph[maxn][maxn];//構建的圖
int visit[maxn];//v2的點是否訪問過
int girl[maxn];//v1所匹配的y;

bool dfs(int x)
{
    for(int i=1;i<=v2;i++)
    {
        if(graph[x][i]&&!visit[i])
        {
            visit[i]=1;
            if(girl[i]==0||dfs(girl[i]))
            {
                girl[i]=x;
                return true;
            }
        }
    }
    return false;
}

void solve()
{
    memset(girl,0,sizeof(girl));
    int cnt=0;
    for(int i=1;i<=v1;i++)
    {
        memset(visit,0,sizeof(visit));//清空上次搜索的標記
        if(dfs(i))
            cnt++;
    }
    cout << cnt << endl;
}

int main()
{
    int n,m;
    scanf("%d %d",&n,&m);
    v1=v2=n;
    memset(graph,0,sizeof(graph));
    for(int i=0;i<m;i++)
    {
        int x,y;
        scanf("%d %d",&x,&y);
        graph[x][y]=1;
    }
    solve();
    return 0;
}


初學匈牙利算法,大體明白怎麼回事了,以後追加新的理解。

發佈了46 篇原創文章 · 獲贊 6 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章