程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 西電1228 最大匹配 二分匹配求最大的組數

西電1228 最大匹配 二分匹配求最大的組數

編輯:C++入門知識

Problem 1228 - 最大匹配 Time Limit: 1000MS   Memory Limit: 65536KB  Difficulty: Total Submit: 220  Accepted: 31  Special Judge: No Description 有N個人手牽著手(當然可能有的人沒有跟其他任何人牽手),現在需要將他們分組,只有直接牽著手的兩個人才有可能分到一組,問最多能分多少組?ps:因為每個人只有兩只手,最多只能牽兩個人 Input 有多組數據 每組第一行為兩個正整數N,M,表示N個人,M個牽手關系。(1<=N,M<=10000) 接下來M行每行兩個正整數a,b表示a,b兩個牽著手(1<=a,b<=n,a!=b,保證a,b不會重復) Output 對於每組數據,輸出一行,一個正整數即最大能分配的組數 Sample Input 3 3 1 2 2 3 1 3 Sample Output 1 Hint Source cyin   題意: 輸入n m  n個點 m個對 輸入m個對  每對表示 a b 可以為一組     (一組只能有2個人,而且1個人不能在2個組中  只有2個人才能組成一個組  。一個人只有2只手  只能牽2個人) 問最多能組成多少個組           思路 :       二分匹配       [cpp]   #include<stdio.h>   #include<iostream>   #include<algorithm>   #include<string.h>   #include<vector>   using namespace std;   const int MAXN=11111;//根據點的個數變   int linker[MAXN];   bool used[MAXN];   vector<int>map[MAXN];   int uN;   bool dfs(int u)   {           for(int i=0;i<map[u].size();i++)               {                   if(!used[map[u][i]])                       {                           used[map[u][i]]=true;                           if(linker[map[u][i]]==-1||dfs(linker[map[u][i]]))                               {                                   linker[map[u][i]]=u;                                   return true;                           }                       }               }           return false;       }   int hungary()   {           int u;           int res=0;           memset(linker,-1,sizeof(linker));           for(u=0;u<uN;u++)               {                   memset(used,false,sizeof(used));                   if(dfs(u)) res++;               }           return res;       }   int main()   {       int u,k,v,i;           int n,m;           while(scanf("%d %d",&n,&m)!=EOF)               {                   for( i=0;i<MAXN;i++)                           map[i].clear();           for(i=0;i<m;i++)           {               scanf("%d %d",&v,&u);                  v=v-1;//如果點是從1開始計數的 要減1  如果從0開始去掉這句以及下面那句               u=u-1;               map[u].push_back(v);                       map[v].push_back(u);               }           uN=n;               printf("%d\n",hungary()/2);           }           return 0;       }                   由於只能牽2個人的手 那麼可以用並查集做       每個人只能只有一個父親節點 且只有一個兒子節點   那麼能牽手的人組成了一條線      那麼這個線上的人 每2個成為一組  線上人數除以2   加上所有線上的結果就是答案   [cpp]   #include <stdio.h>   #include <string.h>   int ss[10022];   int a[10022];   int f(int x)   {       while(x!=a[x])           x=a[x];       return a[x];   }   int main()   {       int i,j,m,n;       int x1,x2;       while(scanf("%d%d",&n,&m)!=EOF)       {           for(i=1;i<=n;i++)           {               a[i]=i;               ss[i]=0;           }           memset(ss,0,sizeof(ss));           while(m--)           {               scanf("%d%d",&x1,&x2);               x1=f(x1);               x2=f(x2);               if(x1<x2)               {                   a[x2]=x1;               }               else                   a[x1]=x2;           }           int s=0;           for(i=1;i<=n;i++)           {               ss[f(a[i])]++;           }           for(i=1;i<=n;i++)           {               s=s+ss[i]/2;           }           printf("%d\n",s);       }       return 0;   }    

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