Submission #792830

#TimeUsernameProblemLanguageResultExecution timeMemory
792830ducanhle_Railway (BOI17_railway)C++14
100 / 100
135 ms40740 KiB
#include<iostream>
#include<vector>
#include<unordered_map>
#include<cstdio>
#include<algorithm>

using namespace std;

int n, m, k;

vector<vector<int> > T, ID, ministersInCity;
vector<int> biggestChild, passiveMinisters, onDFSStack, ministerNumCities, importantTracks;

void initialize() {
 	scanf("%d%d%d", &n, &m, &k);
   	
   	passiveMinisters = vector<int> (n, 0); 
   	biggestChild = vector<int> (n, -1);
   	
	//onDFSStack = vector<bool> (n, false);
	for(int i = 0; i < n; ++i) onDFSStack.push_back(false);
    	
	T = vector<vector<int> > (n, vector<int>());
	ID = vector<vector<int> > (n, vector<int>());
	ministersInCity = vector<vector<int> > (n, vector<int>());
    		
   	for(int i = 1; i <= n-1; ++i) {
   		int u, v;
		scanf("%d%d", &u, &v);
   		T[--u].push_back(--v);
   		T[v].push_back(u);
   		ID[u].push_back(i);
   		ID[v].push_back(i);
   	}
		
   	ministerNumCities = vector<int> (m, 0); 
   	for(int i = 0; i < m; ++i) {
   		int si;
		scanf("%d", &si);
		ministerNumCities[i] = si;
    	for(int j = 0; j < si; ++j) {
    		int city;
			scanf("%d", &city);
			ministersInCity[--city].push_back(i);
    	}
   	}
}
    
// when this is over biggestChild[pos] = u for child u with largest subtree. 
int makeBiggestChildDFS(int pos) {
	onDFSStack[pos] = true;
   	int biggestSize = -1, myBiggestChild = -1, ans = 1;
	for(int i = 0; i < T[pos].size(); ++i) {
		int ch = T[pos][i];
   		if(onDFSStack[ch]) continue;
   		int mySize = makeBiggestChildDFS(ch);
   		ans += mySize;
   		if(biggestSize < mySize) {
   			biggestSize = mySize;
   			myBiggestChild = ch;
   		}
   	}
   	biggestChild[pos] = myBiggestChild;
	onDFSStack[pos] = false;
   	return ans;
}
    
// returns for each minister below the tree how many times he appears below the tree
// sets passive-ministers = number of ministers that have appeared entirely in the subtree
// counts the number of important edges
void DFS(int pos, int edgeID, unordered_map<int, int> &ministers) {	
	//cerr << "in " << pos << endl;
	onDFSStack[pos] = true;
	
	if(biggestChild[pos] >= 0) {
		int bigChildPos;
		for(bigChildPos = 0; bigChildPos < T[pos].size(); ++bigChildPos) {if(T[pos][bigChildPos] == biggestChild[pos]) break;}
		DFS(biggestChild[pos], ID[pos][bigChildPos], ministers);
		passiveMinisters[pos] = passiveMinisters[biggestChild[pos]];
	}


	
	unordered_map<int, int> newMinisters;
	for(int i = 0; i < T[pos].size(); ++i) {

		int ch = T[pos][i];

		int chID = ID[pos][i];

		if(onDFSStack[ch] || ch == biggestChild[pos]) continue;
		
 		newMinisters.clear();
		DFS(ch, chID, newMinisters);

		for(auto it = newMinisters.begin(); it != newMinisters.end(); it++) {
			int minister = (*it).first;
			int numOccurences = (*it).second;
			int totalOccurences = ministers[minister] + numOccurences;
			ministers[minister] = totalOccurences;
			if(ministers[minister] == ministerNumCities[minister]) {passiveMinisters[pos]++;}
		}
   	}
		
   	for(int i = 0; i < ministersInCity[pos].size(); ++i) {
		int minister = ministersInCity[pos][i];
		int totalOccurences = ministers[minister] + 1;
		ministers[minister] = totalOccurences;
		if(ministers[minister] == ministerNumCities[minister]) {passiveMinisters[pos]++;}
	}
	
   	if(ministers.size() - passiveMinisters[pos] >= k) importantTracks.push_back(edgeID);
	onDFSStack[pos] = false;	
	//cerr << "out " << pos << endl;
}
    
int main() {
   	initialize();
   	makeBiggestChildDFS(0);
	unordered_map<int, int> dummy;
	DFS(0, -1, dummy);
    	
   	sort(importantTracks.begin(), importantTracks.end());
    printf("%d\n", importantTracks.size());	
   	
   	for(int i = 0; i + 1 < importantTracks.size(); ++i) {printf("%d ", importantTracks[i]);}		
	if(importantTracks.size() != 0) {
		printf("%d\n", importantTracks[importantTracks.size() - 1]); 
	} 
}

Compilation message (stderr)

railway.cpp: In function 'int makeBiggestChildDFS(int)':
railway.cpp:53:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   53 |  for(int i = 0; i < T[pos].size(); ++i) {
      |                 ~~^~~~~~~~~~~~~~~
railway.cpp: In function 'void DFS(int, int, std::unordered_map<int, int>&)':
railway.cpp:77:36: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |   for(bigChildPos = 0; bigChildPos < T[pos].size(); ++bigChildPos) {if(T[pos][bigChildPos] == biggestChild[pos]) break;}
      |                        ~~~~~~~~~~~~^~~~~~~~~~~~~~~
railway.cpp:85:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   85 |  for(int i = 0; i < T[pos].size(); ++i) {
      |                 ~~^~~~~~~~~~~~~~~
railway.cpp:105:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  105 |     for(int i = 0; i < ministersInCity[pos].size(); ++i) {
      |                    ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
railway.cpp:112:49: warning: comparison of integer expressions of different signedness: 'std::unordered_map<int, int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  112 |     if(ministers.size() - passiveMinisters[pos] >= k) importantTracks.push_back(edgeID);
      |        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
railway.cpp: In function 'int main()':
railway.cpp:124:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wformat=]
  124 |     printf("%d\n", importantTracks.size());
      |             ~^     ~~~~~~~~~~~~~~~~~~~~~~
      |              |                         |
      |              int                       std::vector<int>::size_type {aka long unsigned int}
      |             %ld
railway.cpp:126:26: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  126 |     for(int i = 0; i + 1 < importantTracks.size(); ++i) {printf("%d ", importantTracks[i]);}
      |                    ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
railway.cpp: In function 'void initialize()':
railway.cpp:15:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   15 |   scanf("%d%d%d", &n, &m, &k);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~
railway.cpp:29:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   29 |   scanf("%d%d", &u, &v);
      |   ~~~~~^~~~~~~~~~~~~~~~
railway.cpp:39:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   39 |   scanf("%d", &si);
      |   ~~~~~^~~~~~~~~~~
railway.cpp:43:9: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   43 |    scanf("%d", &city);
      |    ~~~~~^~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...