Submission #254908

#TimeUsernameProblemLanguageResultExecution timeMemory
254908LawlietBridges (APIO19_bridges)C++17
59 / 100
3085 ms7908 KiB
#include <bits/stdc++.h>
 
using namespace std;
typedef pair<int,int> pii;
 
const int MAXN = 100010;
 
int n, m, q;
int raizQ;
 
int ans[MAXN];
int indInside[MAXN];
int lastWeight[MAXN];
int anc[MAXN], sz[MAXN];
int U[MAXN], V[MAXN], W[MAXN];
 
bool mark[MAXN];
bool insideBlock[MAXN];
 
vector<int> adj[MAXN];
 
vector<pii> queries;
vector< pair<int,pii> > sweep;
 
int find(int cur)
{
	if( anc[cur] == cur ) return cur;
	return anc[cur] = find( anc[cur] );
}
 
void join(int i, int j)
{
	i = find(i); j = find(j);
 
	if( i == j ) return;
 
	if( sz[i] < sz[j] )
		swap( i , j );
 
	anc[j] = i;
	sz[i] += sz[j];
}
 
bool isUpdate(int i)
{
	int val = queries[i].second;
	return ( val > 0 );
}
 
void initDSU()
{
	for(int i = 1 ; i <= n ; i++)
		sz[i] = 1, anc[i] = i;
}
 
int DFS(int cur)
{
	mark[cur] = true;
	int ans = sz[cur];
 
	for(int i = 0 ; i < (int)adj[cur].size() ; i++)
		if( !mark[ adj[cur][i] ] ) ans += DFS( adj[cur][i] );
 
	return ans;
}
 
int main()
{
	scanf("%d %d",&n,&m);
 
	for(int i = 1 ; i <= m ; i++)
		scanf("%d %d %d",&U[i],&V[i],&W[i]);
 
	scanf("%d",&q);
	raizQ = sqrt(q) + 1;
 
	for(int i = 1 ; i <= q ; i++)
	{
		int type;
		scanf("%d",&type);
 
		if( type == 1 )
		{
			int edge, newW;
			scanf("%d %d",&edge,&newW);
 
			queries.push_back( { newW , edge } );
		}
		if( type == 2 )
		{
			int s, maxW;
			scanf("%d %d",&s,&maxW);
 
			queries.push_back( { maxW , -s } );
		}
 
		ans[i - 1] = -1;
	}
 
	int lastBlock = (q - 1)/raizQ;
 
	for(int block = 0 ; block <= lastBlock ; block++)
	{
		//printf("+============================+ Processando bloco %d\n",block);
 
		int L = block*raizQ;
		int R = (block + 1)*raizQ - 1;
		R = min( R , q - 1 );
 
		for(int i = 1 ; i <= m ; i++)
		{
			lastWeight[i] = W[i];
			insideBlock[i] = false;
		}
 
		vector<int> inside;
 
		for(int i = L ; i <= R ; i++)
		{
			if( isUpdate( i ) ) 
			{
				int edge = queries[i].second;
 
				if( !insideBlock[edge] )
				{
					indInside[edge] = (int)inside.size();
 
					//printf(".. edge = %d\n",edge);
					insideBlock[edge] = true;
					inside.push_back( edge );
				}
			}
		}
 
		for(int i = 0 ; i < L ; i++)
		{
			if( isUpdate( i ) )
			{
				int newW = queries[i].first;
				int edge = queries[i].second;
 
				lastWeight[edge] = newW;
			}
		}
 
		sweep.clear();
 
		for(int i = 1 ; i <= m ; i++)
			if( !insideBlock[i] ) sweep.push_back( { lastWeight[i] , { U[i] , V[i] } } );//, printf("Adicionei %d: %d -> %d com peso %d\n",i,U[i],V[i],lastWeight[i]);
 
		for(int i = L ; i <= R ; i++)
		{
			if( !isUpdate( i ) )
			{
				int maxW = queries[i].first;
				int source = -queries[i].second;
 
				//printf("Achei query %d %d\n",source,maxW);
 
				sweep.push_back( { maxW , { -source , i } } );
			}
		}
 
		//printf("\n\n\n");
		//printf("------- Sweep Algorithm\n");
 
		sort( sweep.begin() , sweep.end() );
 
		initDSU();
 
		for(int i = (int)sweep.size() - 1 ; i >= 0 ; i--)
		{
			int type = 0;
			if( sweep[i].second.first < 0 ) type = 1;
 
			if( type == 0 )//Update
			{
				int curU = sweep[i].second.first;
				int curV = sweep[i].second.second;
 
				//printf("Juntei %d %d\n",curU,curV);
 
				join( curU , curV );
			}
			if( type == 1 )
			{
				int maxW = sweep[i].first;
				int ind = sweep[i].second.second;
				int source = -sweep[i].second.first;
 
				//printf("Respondendo query maxW = %d source = %d ind = %d\n",maxW,source,ind);
 
				vector<int> weightInside;
 
				for(int j = 0 ; j < (int)inside.size() ; j++)
					weightInside.push_back( lastWeight[ inside[j] ] );
 
				for(int j = L ; j < ind ; j++)
				{
					if( isUpdate( j ) )
					{
						int newW = queries[j].first;
						int edge = queries[j].second;
				
						weightInside[ indInside[edge] ] = newW;
					}
				}

				vector<int> nodes;
 
				for(int j = 0 ; j < (int)inside.size() ; j++)
				{
					//printf("...... Tentando colocar %d -> %d com peso %d\n",U[ inside[j] ],V[ inside[j] ],weightInside[j]);
					if( weightInside[j] >= maxW ) 
					{
						int curU = find( U[ inside[j] ] );
						int curV = find( V[ inside[j] ] );

						if( !mark[curU] ) nodes.push_back( curU ), mark[curU] = true;
						if( !mark[curV] ) nodes.push_back( curV ), mark[curV] = true;
 
						adj[curU].push_back( curV );
						adj[curV].push_back( curU );
					}
				}

				nodes.push_back( find(source) );

				for(int i = 0 ; i < (int)nodes.size() ; i++)
					mark[ nodes[i] ] = false;
 
				ans[ind] = DFS( find(source) );

				for(int i = 0 ; i < (int)nodes.size() ; i++)
					mark[ nodes[i] ] = false, adj[ nodes[i] ].clear();
			}	
		}
	}
 
	for(int i = 0 ; i < q ; i++)
		if( ans[i] != -1 ) printf("%d\n",ans[i]);
}

Compilation message (stderr)

bridges.cpp: In function 'int main()':
bridges.cpp:69:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d %d",&n,&m);
  ~~~~~^~~~~~~~~~~~~~~
bridges.cpp:72:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d %d %d",&U[i],&V[i],&W[i]);
   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bridges.cpp:74:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d",&q);
  ~~~~~^~~~~~~~~
bridges.cpp:80:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d",&type);
   ~~~~~^~~~~~~~~~~~
bridges.cpp:85:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    scanf("%d %d",&edge,&newW);
    ~~~~~^~~~~~~~~~~~~~~~~~~~~
bridges.cpp:92:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    scanf("%d %d",&s,&maxW);
    ~~~~~^~~~~~~~~~~~~~~~~~
#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...