poj3020_无向图最小路径覆盖
这个题目的大意是:在一个矩阵中,*代表城市,要对这些城市覆盖无线网,每一个无线网可以覆盖最多两个城市,求将这些城市都覆盖上无线网时需要最小的无线网个数。
因为无线网最多可以覆盖两个城市,也就是要找在两个城市中间的一条边,这让我想到了是最短路径覆盖问题,由于没有方向性的问题,所以确定为无向图的最短路径覆盖问题。
编程过程中出现了一些问题:
1.一开始在选择数据结构的时候考虑不足,开了一个二维数组存储城市的*和O,其实没有必要存储*和o,只需要在这个二维数组中记录城市的标号即可。
2.在使用scanf()时出现bug,scanf(“%c”)会接受回车,所以应该在必要的地方用getchar()吸收回车,这个问题也纠结了一会儿。
3.粗心问题,在写匈牙利算法的时候if(res[j]==0 || find(res[j])) ||写成&&,唉,细心!!!
以下是代码:
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <memory.h> 4 using namespace std; 5 6 int map[41][11]; //存储城市的标号 7 8 bool array[445][445]; 9 int res[445]; 10 bool use[445]; 11 int v1,v2; 12 13 int row[4]={0,0,-1,1}; 14 int col[4]={-1,1,0,0}; 15 16 bool find(int i) 17 { 18 int j; 19 for(j=1;j<=v2;j++) 20 { 21 if(array[i][j] && !use[j]) 22 { 23 use[j]=true; 24 if(res[j]==0 || find(res[j])) 25 { 26 res[j]=i; 27 return true; 28 } 29 } 30 } 31 return false; 32 } 33 34 int main() 35 { 36 int num,i,j,k; 37 int r,c; 38 int cnt; 39 int result; 40 char ch; 41 scanf("%d",&num); 42 while(num--) 43 { 44 result=0; 45 cnt=1; 46 memset(map,0,sizeof(map)); 47 memset(array,false,sizeof(array)); 48 memset(res,0,sizeof(res)); 49 scanf("%d%d",&r,&c); 50 getchar(); //oooo!!!! 51 52 for(i=0;i<r;i++) 53 { 54 for(j=0;j<c;j++) 55 { 56 scanf("%c",&ch); 57 if(ch=='*') 58 { 59 map[i][j]=cnt; 60 cnt++; 61 } 62 } 63 if(j==c) getchar(); 64 } 65 66 for(i=0;i<r;i++) //构图 67 for(j=0;j<c;j++) 68 if(map[i][j]>0) 69 { 70 int t1=map[i][j]; 71 for(k=0;k<4;k++) 72 if(i+row[k]<=40 && i+row[k]>=0 && j+col[k]>=0 && j+col[k]<=10 && map[i+row[k]][j+col[k]]>0)//注意范围的控制 73 { 74 int t2=map[i+row[k]][j+col[k]]; 75 array[t1][t2]=true; 76 } 77 } 78 79 v1=v2=cnt-1; 80 for(i=1;i<=v1;i++) 81 { 82 memset(use,false,sizeof(use)); 83 if(find(i)) 84 result++; 85 } 86 printf("%d\n",v1-result/2); 87 } 88 return 0; 89 } 90 91 /* 92 1 93 3 3 94 *oo 95 *** 96 o*o 97 */