程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 1498 二分圖—最小點覆蓋

hdu 1498 二分圖—最小點覆蓋

編輯:C++入門知識

/*

題目大意:有 n*n 的矩陣中放著 1-50 種氣球,每次只能毀掉一行或者一列。求 k 此操作後那些氣球不能被全部毀掉。

解題思路:對於每一種給定的color,當 map[i][j] = color  時可以認為存在一條 i—j 的路徑,這樣就可以構建一個二分圖,二分圖的兩個點集分別是該顏色氣球的橫縱坐標;毀掉該 colo r的所有氣球所需的次數就是該二分圖的最小點覆蓋。

什麼是圖的點覆蓋


*/


[cpp]
#include<stdio.h>  
#include<string.h>  
#define M 105  
#define N 55  
int map[M][M],link[M],flag[M],ans[N],n,k;   //注意:link和flag數組長度應該和矩陣的行列數相等;  
int find(int i,int color) 

    int j; 
    for(j=1;j<=n;j++){ 
        if(map[i][j]==color&&flag[j]==0){ 
            flag[j]=1; 
            if(link[j]==0||find(link[j],color)==1){ 
                link[j]=i; 
                return 1; 
            } 
        } 
    } 
    return 0; 

int getnum(int color) 

    int i,sum; 
    memset(link,0,sizeof(link)); 
    for(i=1,sum=0;i<=n;i++){ 
        memset(flag,0,sizeof(flag)); 
        if(find(i,color)==1) 
            sum++; 
    } 
    return sum; 

int main() 

    int i,j,t; 
    while(scanf("%d%d",&n,&k),n||k){ 
        memset(map,0,sizeof(map)); 
        memset(ans,0,sizeof(ans)); 
        for(i=1;i<=n;i++){ 
            for(j=1;j<=n;j++){ 
                scanf("%d",&map[i][j]); 
            } 
        } 
        for(i=1,t=0;i<=50;i++){     //注意這裡是遍歷每一種顏色,所以循環次數等於所有顏色數  
            if(getnum(i)>k) 
                ans[t++]=i; 
        } 
        if(t==0) 
            printf("-1\n"); 
        else{ 
            for(i=0;i<t;i++){ 
                printf(i==0?"%d":" %d",ans[i]); 
            } 
            printf("\n"); 
        } 
    } 
    return 0; 

#include<stdio.h>
#include<string.h>
#define M 105
#define N 55
int map[M][M],link[M],flag[M],ans[N],n,k;   //注意:link和flag數組長度應該和矩陣的行列數相等;
int find(int i,int color)
{
 int j;
 for(j=1;j<=n;j++){
  if(map[i][j]==color&&flag[j]==0){
   flag[j]=1;
   if(link[j]==0||find(link[j],color)==1){
    link[j]=i;
    return 1;
   }
  }
 }
 return 0;
}
int getnum(int color)
{
 int i,sum;
 memset(link,0,sizeof(link));
 for(i=1,sum=0;i<=n;i++){
  memset(flag,0,sizeof(flag));
  if(find(i,color)==1)
   sum++;
 }
 return sum;
}
int main()
{
 int i,j,t;
 while(scanf("%d%d",&n,&k),n||k){
  memset(map,0,sizeof(map));
  memset(ans,0,sizeof(ans));
  for(i=1;i<=n;i++){
   for(j=1;j<=n;j++){
    scanf("%d",&map[i][j]);
   }
  }
  for(i=1,t=0;i<=50;i++){     //注意這裡是遍歷每一種顏色,所以循環次數等於所有顏色數
   if(getnum(i)>k)
    ans[t++]=i;
  }
  if(t==0)
   printf("-1\n");
  else{
   for(i=0;i<t;i++){
    printf(i==0?"%d":" %d",ans[i]);
   }
   printf("\n");
  }
 }
 return 0;
}

 

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