程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 1466 Girls and Boys(最大獨立點集)

POJ 1466 Girls and Boys(最大獨立點集)

編輯:C++入門知識

題意:有n個學生,其中他們之間某些人有聯系,問你最多能找出多少個學生組成一個集合,使得這個集合內的學生任何兩個之間沒有聯系。

 

思路:最大獨立集問題:在N個點的圖G中選出m個點,使這m個點兩兩之間沒有邊.求m最大值.如果圖G滿足二分圖條件,則可以用二分圖匹配來做.最大獨立集點數 = N - 最大匹配數/2,然後就是匈牙利算法實現了。

 

> 這個問題拆點後的二分圖為男在一邊,女的在另一邊。因此如果確定為一邊的點,就不可能於同一邊的點相連。而且由於在尋找最大匹配時不是枚舉其中一邊的點,而是枚舉兩邊的所有點,所以得到的ans為最大匹配數 的兩倍,因為每條匹配的邊都算了兩遍。
 
代碼:
[cpp] 
<span style="font-size:18px;">#include <iostream> 
#include <algorithm> 
#include <cmath> 
using namespace std; 
const int MAXN=125; 
int uN,vN;   
int map[MAXN][MAXN]; 
int match[MAXN]; 
bool visit[MAXN];  
bool search(int u){ 
    int v; 
    for(v=1;v<=vN;v++) 
        if(map[u][v]&&!visit[v]){ 
            visit[v]=true; 
            if(match[v]==-1||search(match[v])){ 
                match[v]=u; 
                return true; 
            } 
        } 
    return false; 

 
int hungary(){ 
    int res=0; 
    int u; 
    memset(match,-1,sizeof(match)); 
    for(u=1;u<=uN;u++){ 
        memset(visit,0,sizeof(visit)); 
        if(search(u))  res++; 
    } 
    return res; 

long long a[1010]; 
 
int main(){ 
    int t; 
    int n; 
    int i, j,m,a,b; 
    scanf("%d", &t); 
    while(t --){ 
        scanf("%d%d", &n,&m); 
        memset(map, 0, sizeof(map)); 
        uN = n; 
        vN = n; 
        for(i = 0; i < m ; i ++){ 
             scanf("%d%d",&a,&b); 
             map[a][b]=1; 
        } 
        int ans = n - hungary(); 
        printf("%d\n", ans); 
    } 
    return 0; 

</span> 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved