The first topic means there are N cities and M radar. You can use a maximum of k radar and ask how much radius you can use to make the K radar cover n cities.
The second is the nine-wild to choose K cities from N cities to build an airport, ask the smallest maximum city distance is how much
It's all dance chains + pruning + Two-point computing path
Paste the second question code
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath>using namespace std; const int M = 110;const int n = 30000;const int inf = 0x3f3f3f3f;const Double EP = 1e-8;int k;struct DLX {int N, m,si Ze int u[n],d[n],r[n],l[n],row[n],col[n]; int ans[m],s[m]; int ANSD; void init (int a,int b) {n = A; m = b; for (int i=0; i<=m; i++) {s[i] = 0; U[i] = d[i] = i; L[i] = i-1; R[i] = i+1; } R[m] = 0; L[0] = m; size = m; for (int i=1; i<=n; i++) Ans[i] =-1; } void AddRow (int r,int c) {++s[col[++size]=c]; Row[size] = r; D[size] = D[c]; U[D[C]] = size; U[size] = c; D[C] = size; if (ans[r]<0) ans[r] = l[size] = r[size] = size; else {r[size] = R[ans[r]]; L[R[ANS[R]] = size; L[size] = Ans[r]; R[ANS[R]] = size; } } void remove (int c) {for (int i= d[c]; i!=c; I=d[i]) {L[r[i]] = l[i]; R[l[i]] = r[i]; }} void resume (int c) {for (int i = u[c]; i!=c; I=u[i]) {L[r[i]]=r[l[i]] = i; }} bool V[n]; int f () {int ret = 0; for (int c =r[0]; c!=0; c=r[c]) v[c] = true; for (int c = r[0]; c!=0; C=r[c]) {if (V[c]) {ret++; V[C] = false; For (int. i=d[c]; i!=c; I=d[i]) {for (int j=r[i]; j!=i; J=r[j]) {v[col[j]]=false; }}}} return ret; } bool Dance (int d) {if (d+f () >k) return false; if (r[0]==0) return d<=k; int c = r[0]; for (int i=r[0]; i!=0; I=r[i]) {if (S[i]<s[c]) {c=i; }} for (int i=d[c]; i!=c; I=d[i]) {remove (i); for (int j=r[I]; J!=i; J=R[J]) Remove (j); if (dance (d+1)) return true; for (int j=l[i]; j!=i; J=l[j]) resume (j); Resume (i); } return false; }} g;struct node{int x; int y;} Point[n],radar[n]; Long Long Dis (node A,node b) {return (Long Long) abs (a.x-b.x) + (Long Long) abs (A.Y-B.Y);} int T;int N,m,p;int Main () {int cas = 0;scanf ("%d", &t), while (t--) {scanf ("%d%d", &n,&k); for (int i=1;i<=n; i++) {scanf ("%d%d", &POINT[I].X,&POINT[I].Y);} /* for (int i=1;i<=n;i++) {for (int j=1;j<=m;j++) {printf ("%f", Dis (point[i],radar[j] )); } puts (""); } */long long ans = 0;long long l= 0;long Long r = 100000000000ll;while (R >= L) {//puts (" OK "); G.init (N,n); Long Long mid = (l+r)/2; for (int i=1;i<=n;i++) {for (int j=1;j<=n;j++) {if (Dis (point[i],point[J]) <= mid) {G.addrow (j,i); }}} if (G.dance (0)) {r = mid-1; ans = mid;} else L = mid + 1;} printf ("Case #%d:%i64d\n", ++cas,ans);}}
Copyright notice: All brothers, please feel free to reprint, please indicate who is the brother
HDU 2295 &&hdu 5046