HDOJ3101 LA4226 The Heart of the Country 简单模拟

The Heart of the Country

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 299    Accepted Submission(s): 99


Problem Description
The nation of Graphia is at war. The neighboring nations have for long watched in jealousy as Graphia erected prosperous cities and connected them with a network of highways. Now they want a piece of the pie.

Graphia consists of several cities, connected by highways. Graphian terrain is rough, so the only way to move between the cities is along the highways. Each city has a certain number of troops quartered there. Graphia's military command knows that it will require a certain number of troops, K , to defend any city. They can defend a city with the troops stationed there, supported by the troops in any other city which is directly connected with a highway, with no cities in between. Any troops further away than that simply cannot get there in time. They also know that their enemies will onlyattack one city at a time -- so the troops in a city can be used to defend that city, as well as any of its neighbors. However, if a city can't be defended, then the military command must assume that the troops quartered in that city will be captured, and cannot aid in the defense of Graphia. In the case below, suppose K = 10 . City C might seem well defended, but it will eventually fall.



Graphia's leadership wants to identify the Heart of their country -- the largest possible group of cities that can mutually defend each other, even if all of the other cities fall.

More formally, a city is defensible if it can draw a total of at least K troops from itself, and from cities directly adjacent to it. A set of cities is defensible if every city in it is defensible, using only troops from itself and adjacent cities in that set. The Heart of the country is the largest possible defensible set of cities - that is, no other defensible set of cities has more cities in it.
 

Input
There will be several data sets. Each set begins with two integers, N and K , where N is the number of cities ( 3<=N<=1000 ), and K is the number of troops required to defend a city. The cities are numbered 0 through N - 1 .

On the next N lines are descriptions of the cities, starting with city 0. Each of the city description lines begins with an integer T , indicating the number of troops quartered in that city ( 0<=T<=10000 ). This is followed by an integer M , indicating the number of highways going out of that city, and then M integers, indicating the cities those highways go to. No two highways will go from and to the same cities, so every city in each list will be unique. No highway will loop from a city back to the same city. The highways go both ways, so that if city I is in city J 's list, then it's guaranteed that city J will be in city I 's list in the input. The input will end with a line with two space-separated 0's.
 

Output
For each data set, print two integers on a single line: The number of cities in the heart of the country, and the number of troops in the heart of the country. Print a space between the integers. There should be no blank lines between outputs.
 

Sample Input
  
  
4 900 100 2 1 2 200 2 0 3 500 2 0 3 1000 2 1 2 4 900 100 3 1 2 3 200 3 0 3 2 500 3 1 3 0 1000 3 2 1 0 0 0
 

Sample Output
  
  
3 1700 4 1800
 

Source
 

Recommend
gaojie   |   We have carefully selected several similar problems for you:   3103  3102  3105  3107  3106 

分析:预处理O(n^2)复杂度,因为每次都要查找不能被守卫的城市。有可能当前城市可以守卫,但某次查找之后,与它连接的其他城市不能守卫了,导致该城市也无法守卫,就像题目显示的那张图的城市C。
每次查找最少会删除一个城市,所以要继续查找。如果删除城市个数为0,那就退出查找操作。
最后遍历一遍,统计所有的可以守卫的城市以及它们的军队人数总和。

代码如下:
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

const int maxn = 1000+5;
int n,k,tot;
vector<int>G[maxn];
bool f[maxn];
int troop[maxn];
int num,tr;


void init(){
    int T,city;
    memset(f,1,sizeof(f));
    for (int i=0; i<n; i++) G[i].clear();
    for (int i=0; i<n; i++) {
         scanf("%d %d",&troop[i],&T);
         for (int j=1; j<=T;j++) {
            scanf("%d",&city);
            G[i].push_back(city);
         }
    }
}

void select(){
    int total_tr;
    bool isfound;
    for (int i=0; i<n; i++) {
        isfound = 0;
        for (int j=0; j<n; j++) if (f[j]) {
            total_tr = troop[j];
            for (int p=0; p<G[j].size(); p++) if (f[G[j][p]]) total_tr += troop[G[j][p]];
            if (total_tr<k) {f[j] =0; isfound = 1;}
        }
        if (!isfound) return;
    }
}


int main(){
    while (scanf("%d %d",&n,&k)==2){
         if (n<3) break;
         init();
         select();

         num = 0; tr = 0;
         for (int i=0; i<n; i++) if (f[i]){
             num++; tr += troop[i];
         }
         printf("%d %d\n",num,tr);
    }
    return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值