程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HDU 多校聯合練習賽 Warm up 2 二分圖匹配

HDU 多校聯合練習賽 Warm up 2 二分圖匹配

編輯:C++入門知識

Warm up 2
Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 656    Accepted Submission(s): 329


Problem Description
  Some 1×2 dominoes are placed on a plane. Each dominoe is placed either horizontally or vertically. It's guaranteed the dominoes in the same direction are not overlapped, but horizontal and vertical dominoes may overlap with each other. You task is to remove some dominoes, so that the remaining dominoes do not overlap with each other. Now, tell me the maximum number of dominoes left on the board.
 

Input
  There are multiple input cases.
  The first line of each case are 2 integers: n(1 <= n <= 1000), m(1 <= m <= 1000), indicating the number of horizontal and vertical dominoes.
Then n lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x + 1, y).
  Then m lines follow, each line contains 2 integers x (0 <= x <= 100) and y (0 <= y <= 100), indicating the position of a horizontal dominoe. The dominoe occupies the grids of (x, y) and (x, y + 1).
  Input ends with n = 0 and m = 0.
 

Output
  For each test case, output the maximum number of remaining dominoes in a line.
 

Sample Input
2 3
0 0
0 3
0 1
1 1
1 3
4 5
0 1
0 2
3 1
2 2
0 0
1 0
2 0
4 1
3 2
0 0

Sample Output
4
6

Source
2013 Multi-University Training Contest 2
 

Recommend
zhuyuanchen520
 


題解:
原來是我建圖不會建。。。果然是基礎功不扎實啊。。


原來就是個普通的最大獨立集。  最大獨立集的定義就是所選取的點集合中,任意兩條邊都不相連。 又因為題目中說橫著的不會跟橫著的相連,豎著的不會跟豎著的相連,所以。這是個相當標准的二分圖。就是求X集合跟Y集合的最大獨立集。   


建造圖時,X取的是那0到n-1個骨牌   Y取的是後面的0到m-1個骨牌。。。無語撒。。原來當初我2分圖完全弄錯了。。


這題解法好像很多。。什麼搜索,貪心。。不說了。。。牢記不會建圖的教訓。。


我提供下我寫的3份模板代碼吧。。。。


第一份 33MS


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cstring>
const int maxn=1111;
int g[maxn][maxn];
int cx[maxn],cy[maxn],vst[maxn];
int nx,ny;
int findpath(int u){
    for(int v=0;v<ny;v++){
        if(!vst[v]&&g[u][v]){
            vst[v]=1;
            if(cy[v]==-1||findpath(cy[v])){
                cy[v]=u,cx[u]=v;
                return 1;
            }
        }
    }
    return 0;
}
int MaxMatch(){
    int ret=0;
    memset(cx,-1,sizeof(cx));
    memset(cy,-1,sizeof(cy));
    for(int i=0;i<nx;i++)
        if(cx[i]==-1){
            memset(vst,0,sizeof(vst));
            if(findpath(i))
                ret++;
        }
    return ret;
}
struct node{
    int x,y;
}mx[maxn],my[maxn];
int main(){
    //freopen("1009.in","r",stdin);
    int n,m;
    while(scanf("%d %d",&n,&m)&&n+m){
        for(int i=0,a,b;i<n;i++){
            scanf("%d %d",&a,&b);
            mx[i].x=a,mx[i].y=b;
        }
        for(int i=0,a,b;i<m;i++){
            scanf("%d %d",&a,&b);
            my[i].x=a,my[i].y=b;
        }
        memset(g,0,sizeof(g));
        for(int i=0,x1,y1;i<n;i++){
            x1=mx[i].x,y1=mx[i].y;
            for(int j=0,x2,y2;j<m;j++){
                x2=my[j].x,y2=my[j].y;
                if(x1==x2&&y1==y2
                 ||x1==x2&&y1==y2+1
                 ||x1+1==x2&&y1==y2
                 ||x1+1==x2&&y1==y2+1)
                 g[i][j]=1;
            }
        }
        nx=n,ny=m;
        printf("%d\n",n+m-MaxMatch());
    }
    return 0;
}
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#define clr(x,k) memset((x),(k),sizeof(x))
#define foreach(it,c) for(vi::iterator it = (c).begin();it != (c).end();++it)
using namespace std;
typedef vector<int> vi;

const int maxn=1000;
vector<int> gx[maxn];
int cx[maxn],cy[maxn],vst[maxn];
int nx,ny;
int findpath_Vector(int u){
    foreach(it,gx[u]){
        if(!vst[*it]){
            vst[*it]=1;
            if(cy[*it]==-1||findpath_Vector(cy[*it])){
                    cx[u]=*it;
                    cy[*it]=u;
                    return 1;
            }
        }
    }
    return 0;
}
int maxMatch_Vector(){
    int ret=0;
    clr(cx,-1),clr(cy,-1);
    for(int i=0;i<nx;i++)
        if(cx[i]==-1){
                clr(vst,0);
                if(findpath_Vector(i))
                    ret++;
        }
    return ret;
}
struct node{
    int x,y;
}mx[maxn],my[maxn];
int main(){
   // freopen("1009.in","r",stdin);
    int n,m;
    while(scanf("%d %d",&n,&m)&&n+m){
        for(int i=0,a,b;i<n;i++){
            scanf("%d %d",&a,&b);
            mx[i].x=a,mx[i].y=b;
        }
        for(int i=0,a,b;i<m;i++){
            scanf("%d %d",&a,&b);
            my[i].x=a,my[i].y=b;
        }
        for(int i=0;i<n;i++)
            gx[i].clear();
        for(int i=0,x1,y1;i<n;i++){
            x1=mx[i].x,y1=mx[i].y;
            for(int j=0,x2,y2;j<m;j++){
                x2=my[j].x,y2=my[j].y;
                if(x1==x2&&y1==y2
                 ||x1==x2&&y1==y2+1
                 ||x1+1==x2&&y1==y2
                 ||x1+1==x2&&y1==y2+1)
                 gx[i].push_back(j);
            }
        }

        nx=n,ny=m;
        printf("%d\n",n+m-maxMatch_Vector());
    }
    return 0;
}

 

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