Given a network of N cities (numbered from 1 to N) and (N-1) roads arranged in a tree format with the root at city 1.
Each of the (N-1) roads is assigned a value of either 0 or 1.
If the value of a road is 0, it cannot be blocked by the government.
If the value of a road is 1, it may or may not be blocked depending on the decision of the government.
Initially, city numbered 1 is infected by a virus. The infection spreads from an infected to an uninfected city only if no road present on the shortest path between the cities is blocked.
The government wants to control the number of infected cities and has asked you to devise a plan. Determine the minimum number of roads (with value 1) you need to block such that the at mostK cities are infected at the end.
If it is not possible that at mostK cities are infected, print -1.
EXPLANATION:
The first thing we need to calculate is all the subtrees that can be saved if we blocked entry in it. One thing to note here is if we can block entry to a subtree, say subtree T, then we won’t consider the subtrees of T in our final count. We can use a DFS to calculate this.
Thus using DFS we will have an array A of our subtrees, where A[i] denote the strength of the i_{th} subtree, i.e the number of nodes in the i_{th} subtree.
Initially we assume that no road is blocked, so we have n infected cities.
Now sort the array A in descending order and reduce the infected cities by A[i] by blocking entry to the i_{th} subtree till the number of infected is greater than k.
If even after blocking all possible subtrees, the number of infected is greater than k, we give -1 as output, otherwise our final answer would be the number of subtrees that we blocked.
I followed a similar approach, first found the number of nodes in each subtree (including the root of subtree) and then I did bfs from node 1
If for edge (u, v) the road has 1 then i don’t push v in queue but store the number of nodes in subtree at node v. Else push node v in queue.
After that I calculated the answer with the vector.
But this failed the test cases.
Heres my code: CodeChef: Practical coding for everyone
Can someone give any testcases where this fails
@appu_23 Yes, the undirected graph constructed should be independent of ordering of the vertices given in input. Flipping a single edge in the directed graph could change which edges can and cannot be accessed.
same. You probably made the same mistake as I did. For each road you are supposed to add, you are given 2 values: u and v.
In the example test case and the first half test cases, u will always be a city that has been added to the tree before. In the last 5 test cases u may not exist in the tree, but v will.
This means you are most likely missing a check, if your tree contains v but not u, you want to swap u with v.
could anyone help me in finding what is going wrong? 4 passed, rest TLE
tried adjacency matrix, stored road information inside a[r][r] where r is the node that is connected by a parent with given road.
while traversing i m only storing the counts of cities for nodes that are connected by ‘1’ roads and only those that are encountered first in root node’s connections. this way we only track the maximum cities that can be cut out in every sub branch of root node.
#include<bits/stdc++.h>
using namespace std;
int trav(vector<vector<long long int>>&a,int r,vector<long long int>&con,int flag){
//cout<<"node"<<r+1<<endl;
long long int count=0,tm=-1;
if(flag==0 && a[r][r]==1){tm=1;flag=1;}
for(long long int j=0;j<a.size();j++){
if(j==r)continue;
if(a[r][j]==1 || a[r][j]==0){
count+=trav(a,j,con,flag);
}
}
//cout<<r+1<<" "<<count+1<<endl;
if(tm==1){con.push_back(count+1);}
return count+1;
}
int main(){
int t;cin>>t;
while(t--){
long long int n,k;cin>>n>>k;
vector<vector<long long int>>a(n,vector<long long int>(n,-1));
vector<long long int>con;
for(long long int i=0;i<n-1;i++){
long long int d,b,c;cin>>d>>b>>c;
a[b-1][b-1]=c;
a[d-1][b-1]=c;
}
trav(a,0,con,0);
//for(int i=0;i<n;i++)cout<<i+1<<" "<<con[i]<<endl;
sort(con.rbegin(),con.rend());
long long int cc=0,i=0,blocked=0;
while(n-blocked>k){
if(i>=con.size())break;
blocked+=con[i];i++;
cc++;
}
if(n-blocked>k)cout<<"-1"<<endl;
else cout<<cc<<endl;
}
return 0;
}