思路比较显然:二分答案,流流流
但是实现的时候感觉自己数学捉急。。
一开始算了个直线到点距离。。。。
应该是线段到点距离
1 #include <bits/stdc++.h> 2 #define sqr(x) ((x)*(x)) 3 #define MAXN 50000 4 #define TO (n+m+2) 5 #define FROM (n+m+1) 6 #define PO (n+m+2) 7 #define INF 2000000000 8 #define mid (l+r>>1) 9 using namespace std; 10 int n,m,k,LI=2,ans; 11 int to[MAXN],w[MAXN],nex[MAXN],fir[MAXN]; 12 int h[MAXN],qq[MAXN],flo[MAXN],id[MAXN]; 13 int ti[MAXN],x[MAXN],y[MAXN],X[MAXN],Y[MAXN],r[MAXN],p[MAXN],q[MAXN],R[MAXN]; 14 void add(int p,int q,int o) 15 { 16 to[LI]=q;w[LI]=o;nex[LI]=fir[p];fir[p]=LI;LI++; 17 to[LI]=p;w[LI]=0;nex[LI]=fir[q];fir[q]=LI;LI++; 18 } 19 bool bfs()//计算层次图 20 { 21 int head=-1,tail=0; 22 for(int i=0;i<=PO;i++) h[i]=-1; 23 qq[0]=FROM;h[FROM]=0;// h[i]:点i的层数 24 while(head!=tail) 25 { 26 int x=qq[++head]; 27 for(int i=fir[x];i;i=nex[i]) 28 if(flo[i]&&h[to[i]]==-1) 29 { 30 h[to[i]]=h[x]+1; 31 qq[++tail]=to[i]; 32 } 33 } 34 return h[TO]!=-1; 35 } 36 int dfs(int x,int f)//增广路:到点x最大容量为 f 37 { 38 if(x==TO)return f; 39 int w,used=0; 40 for(int i=fir[x];i;i=nex[i]) 41 if(h[to[i]]==h[x]+1) 42 { 43 w=dfs(to[i],min(flo[i],f-used)); 44 flo[i]-=w; flo[i^1]+=w; 45 used+=w;if(used==f)return f; 46 } 47 if(!used)h[x]=-1; 48 return used; 49 } 50 int dinic() //%usqwedf 51 { 52 int ans=0; 53 while(bfs()) 54 ans+=dfs(FROM,1e9); 55 return ans; 56 } 57 bool ok(int time) 58 { 59 for(int i=1;i<=n;i++) 60 w[id[i]]=time/ti[i]+1; 61 for(int i=0;i<LI;i++) 62 flo[i]=w[i]; 63 return(dinic()==m); 64 } 65 int main() 66 { 67 // freopen("1.in","r",stdin); 68 scanf("%d%d%d",&n,&m,&k); 69 for(int i=1;i<=n;i++) 70 scanf("%d%d%d%d",&x[i],&y[i],&r[i],&ti[i]); 71 for(int i=1;i<=m;i++) 72 scanf("%d%d",&X[i],&Y[i]); 73 for(int i=1;i<=k;i++) 74 scanf("%d%d%d",&p[i],&q[i],&R[i]); 75 for(int i=1;i<=n;i++) 76 for(int j=1;j<=m;j++) 77 { 78 bool flag=sqr(x[i]-X[j])+sqr(y[i]-Y[j])<=sqr(r[i]); 79 if(!flag) continue; 80 long long a=y[i]-Y[j],b=X[j]-x[i],c=x[i]*Y[j]-y[i]*X[j]; 81 for(int o=1;o<=k;o++) 82 if(sqr(a*p[o]+b*q[o]+c)<=sqr(R[o])*(sqr(a)+sqr(b)) && (sqr(x[i]-p[o])+sqr(y[i]-q[o])<=sqr(R[o]) || sqr(X[j]-p[o])+sqr(Y[j]-q[o])<=sqr(R[o]))) 83 { 84 flag=0; 85 break; 86 } 87 if(flag) 88 add(i,j+n,1); 89 } 90 for(int i=1;i<=m;i++) 91 add(i+n,TO,1); 92 for(int i=1;i<=n;i++) 93 id[i]=LI,add(FROM,i,0); 94 int l,r; 95 for(l=0,r=4000000;l<r;) 96 if(ok(mid)) r=mid;else l=mid+1; 97 if(ok(l)) 98 printf("%d ",l); 99 else 100 puts("-1"); 101 return 0; 102 }