Sicily 1794. Missiles

1794. Missiles

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

Given a complete undirected graph G = (V, E) representing a map of a continent, each node represents a city. There are two countries, called A and B, in the continent. Country A has N cities and country B has M cities. Country A is a big country (M <= N) and recently the scientists of country A invent a new weapon – A Crotalid Missile (Short for ACM ?). This missile is so powerful that it can destroy one city. President of country A has ordered that every city of his country should be armed with one missile. Of course president of country B knows this news because of the capable spies of his country. He thinks that his country is in dangerous and requires the intelligent scientists to build a missile defense system to prevent the future attack from country A. This defense system must be reliable and effective. But before building the system, the scientists need to know how fast the system should be expected to react to the missile attack. Hence, the minimum time for country A needed to destroy all cities of country B is required to calculated, by you, the most intelligent member of the scientists of country B.

Input

Input may consist of several test data sets. For each data set, it can be format as below:
     First comes one line with one integer K, 2 <= K <= 100, the number of nodes in the graph.
     Then comes K lines, each contains K integer separating with one space, representing the edges of the complete graph. The number of the matrix[i][j] represents the minutes needed by the missile flying from city i to city j. Every integer is between [1, 100]. The matrix is symmetry.
     Then comes one line with one integer N, 1 <= N <= K, the number of cities of country A.
     N lines follow, each line contains one integer which is between [1, K], representing the city number of country A. The integers are distinct. 
     Then comes one line with one integer M, 1 <= M <= K, the number of cities of country B.
     M lines follow, each line contains one integer which is between [1, K], representing the city number of country M. The integers are distinct. 
     You can assume all input data sets are valid.
Input is ended by K = 0.

Output

For each data set, just output one integer in one line, representing the minimum time measured in minutes that the missile would destroy all cities of country B.

Sample Input

2
0 1
1 0
1
2
1
1
3
0 2 1
2 0 10
1 10 0
2
2 3
1
1
0

Sample Output

1

1

// Problem#: 1794
// Submission#: 3592826
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <string.h>

const int MAXN = 111;
int n, g[MAXN][MAXN];
int an, a[MAXN];
int bn, b[MAXN];
int maxd;
char newg[MAXN][MAXN];
char cover[MAXN];
int link[MAXN];

void input() {
    int i, j, k;
    maxd = 0;
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= n; j++) {
            scanf("%d", &g[i][j]);
            maxd = maxd > g[i][j] ? maxd : g[i][j];
        }
    }
    for (k = 1; k <= n; k++) {
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= n; j++) {
                if (g[i][k] + g[k][j] < g[i][j])
                    g[i][j] = g[i][k] + g[k][j];
            }
        }
    }
    scanf("%d", &an);
    for (i = 1; i <= an; i++) scanf("%d", a + i);
    scanf("%d", &bn);
    for (i = 1; i <= bn; i++) scanf("%d", b + i);
}

bool find(int x) {
    int q, i;
    for (i = 1; i <= bn; i++) 
        if (!cover[i] && newg[x][i]) {
            q = link[i];
            link[i] = x;
            cover[i] = 1;
            if (!q || find(q)) return true;
            link[i] = q;
        }
    return false;
}

int max_match() {
    int i, ret = 0;
    memset(link, 0, sizeof(link));
    for (i = 1; i <= an; i++) {
        memset(cover, 0, sizeof(cover));
        find(i);
    }
    for (i = 1; i <= bn; i++) if (link[i]) ret++;
    return ret;
}

int main() {
    int i, j, l, r, mid, ans;
    while (scanf("%d", &n) && n) {
        input();
        l = 1, r = maxd;
        while (l <= r) {
            mid = (l + r) / 2;
            for (i = 1; i <= an; i++)
                for (j = 1; j <= bn; j++)
                    if (g[a[i]][b[j]] <= mid) newg[i][j] = 1;
                    else newg[i][j] = 0;
            if (max_match() == bn) ans = mid, r = mid - 1;
            else l = mid + 1;
        }
        printf("%d\n", ans);
    }
    return 0;
}                                 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值