题解
- 对于这题来说,直接求摧毁时间应该是不可信的,那么考虑二分出一个答案,问题就转换为判断性的了
- 显然导弹的飞行时间应该是要最短,这样的话才能建设一套完美的防御系统
- 那么就可以用Floyd处理出两两城市之间的最短路(k<=100)
- 因为这题要求的其实就是最大匹配,然后在最大匹配里判断飞行是否超过二分出的mid
- 一套防御系统要不全档下,漏掉一个也会挂菜,所有要全部档下才算是一个成功的防御系统
代码
1 #include <cstdio>
2 #include <iostream>
3 #include <cstring>
4 #define N 210
5 using namespace std;
6 int a[N][N],p[N],q[N],bz[N],vis[N],i,n,mid,num1,num2,ans=0;
7 bool xyl(int x)
8 {
9 if (bz[x]==i) return 0;
10 bz[x]=i;
11 for (int i=1;i<=num1;i++)
12 if (a[q[x]][p[i]]<=mid)
13 if (!vis[i]||xyl(vis[i]))
14 { vis[i]=x; return 1; }
15 return 0;
16 }
17 bool check()
18 {
19 memset(bz,0,sizeof(bz)),memset(vis,0,sizeof(vis)),ans=0;
20 for (i=1;i<=num2;i++) if (xyl(i)) ans++; else return 0;
21 if (ans==num2) return 1; else return 0;
22 }
23 int main()
24 {
25 scanf("%d",&n);
26 for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) scanf("%d",&a[i][j]);
27 for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
28 scanf("%d",&num1); for (int i=1;i<=num1;i++) scanf("%d",&p[i]);
29 scanf("%d",&num2); for (int i=1;i<=num2;i++) scanf("%d",&q[i]);
30 int l=1,r=100;
31 while (l+1<r)
32 {
33 mid=l+r>>1;
34 if (check()) r=mid; else l=mid;
35 }
36 mid=l; if (check()) r=l;
37 printf("%d",r);
38 }