题意:给你一个图,图中有宝物和保安两种元素。每个宝物需要周围的某些位置同时安放保安(如果那些位置有宝物,可以把宝物替换成保安)问你最少需要再安置多少保安,可以使所有宝物满足要求。
题意有点难懂
链接:点我
直接建无向图,少判断个奇偶性,最后除个2即可
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<map> 8 using namespace std; 9 #define MOD 1000000007 10 const int INF=0x3f3f3f3f; 11 const double eps=1e-5; 12 typedef long long ll; 13 #define cl(a) memset(a,0,sizeof(a)) 14 #define ts printf("*****\n"); 15 const int MAXN = 5010;//点数的最大值 16 const int MAXM = 50010;//边数的最大值 17 int a[MAXN][MAXN]; 18 int b[MAXN][MAXN]; 19 int n,m,tt; 20 /* 21 * 匈牙利算法邻接表形式 22 * 使用前用init()进行初始化,给uN赋值 23 * 加边使用函数addedge(u,v) 24 * 25 */ 26 struct Edge 27 { 28 int to,next; 29 }edge[MAXM]; 30 int head[MAXN],tot; 31 void init() 32 { 33 tot = 0; 34 memset(head,-1,sizeof(head)); 35 } 36 void addedge(int u,int v) 37 { 38 edge[tot].to = v; edge[tot].next = head[u]; 39 head[u] = tot++; 40 } 41 int linker[MAXN]; 42 bool used[MAXN]; 43 int uN; 44 bool dfs(int u) 45 { 46 for(int i = head[u]; i != -1 ;i = edge[i].next) 47 { 48 int v = edge[i].to; 49 if(!used[v]) 50 { 51 used[v] = true; 52 if(linker[v] == -1 || dfs(linker[v])) 53 { 54 linker[v] = u; 55 return true; 56 } 57 } 58 } 59 return false; 60 } 61 int hungary() 62 { 63 int res = 0; 64 memset(linker,-1,sizeof(linker)); 65 for(int u = 0; u < uN;u++)//点的编号0~uN-1 66 { 67 memset(used,false,sizeof(used)); 68 if(dfs(u))res++; 69 } 70 return res; 71 } 72 int dir[][2] = {{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2}, 73 {2,1},{2,-1},{1,-2},{-1,0},{0,1},{1,0},{0,-1}}; 74 int main() 75 { 76 int i,j,k; 77 #ifndef ONLINE_JUDGE 78 freopen("1.in","r",stdin); 79 #endif 80 int ca=1; 81 while(scanf("%d%d",&n,&m)!=EOF) 82 { 83 if(n==0&&m==0) break; 84 uN = 0; 85 for(i = 0;i < n;i++) 86 for(j = 0;j < m;j++) 87 { 88 b[i][j] = uN++; 89 } 90 for(i=0;i<n;i++) 91 { 92 for(j=0;j<m;j++) 93 { 94 scanf("%d",&a[i][j]); 95 } 96 } 97 init(); 98 for(i=0;i<n;i++) 99 { 100 for(j=0;j<m;j++) 101 { 102 if(a[i][j]!=-1) 103 { 104 for(k=0;k<12;k++) 105 { 106 if(a[i][j]&(1<<k)) //该点需要放置守卫 107 { 108 int nx=i+dir[k][0]; 109 int ny=j+dir[k][1]; 110 if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!=-1) 111 { 112 addedge(b[i][j],b[nx][ny]); 113 addedge(b[nx][ny],b[i][j]); 114 } 115 } 116 } 117 } 118 } 119 } 120 printf("%d. %d\n",ca++,hungary()/2); 121 } 122 }
时间: 2024-11-15 02:19:18