Pagini recente » Monitorul de evaluare | Cod sursa (job #3326563) | Cod sursa (job #571108) | Cod sursa (job #3243204) | Cod sursa (job #3345568)
#include <fstream>
#include <vector>
#include <deque>
#include <utility>
#define x first
#define y second
using namespace std;
ifstream in("obiective.in");
ofstream out("obiective.out");
typedef pair <int, int> pii;
const int nmax = 32000, qmax = 1e5, maxint = (1 << 30);
int n, m, nrq, xx, yy;
vector <int> edges[nmax + 2];
vector <int> revedges[nmax + 2];
vector <int> edgescomp[nmax + 2];
vector <int> revedgescomp[nmax + 2];
int dpswaps[nmax + 2];
int answer[qmax + 2];
int lastt[nmax + 2];
int arrynodes[nmax + 2];
/// ---> get strongly conected components <--- ///
int strongcomponent[nmax + 2];
int visited[nmax + 2];
int toposort[nmax + 2];
int nodescc[nmax + 2];
void dfscomputetopo(int node){
visited[node] = 1;
for(auto nxt : edges[node]){
if(!visited[nxt]) dfscomputetopo(nxt);
}
toposort[++toposort[0]] = node;
return;
}
void dfsmarkcomponents(int node){
strongcomponent[node] = strongcomponent[0];
nodescc[++nodescc[0]] = node;
for(auto nxt : revedges[node]){
if(!strongcomponent[nxt])
dfsmarkcomponents(nxt);
}
return;
}
/// ---> queries in O(n * q) <--- ///
vector <pii> queries[nmax + 2];
void solvestronglycomponent(int xx){
for(int i = 1; i <= strongcomponent[0]; i++){
dpswaps[i] = maxint;
}
deque <int> dq;
dpswaps[xx] = 0;
dq.push_front(xx);
for(int node; !dq.empty(); ){
node = dq.front(); dq.pop_front();
for(auto nxt : edgescomp[node]){
if(dpswaps[nxt] > dpswaps[node])
dpswaps[nxt] = dpswaps[node], dq.push_front(nxt);
}
for(auto nxt : revedgescomp[node]){
if(dpswaps[nxt] > dpswaps[node] + 1)
dpswaps[nxt] = dpswaps[node] + 1, dq.push_back(nxt);
}
}
for(auto qry : queries[xx]){
answer[qry.y] = dpswaps[qry.x];
}
return;
}
int main(){
in>>n>>m;
for(int i = 1; i <= m; i++){
in>>xx>>yy;
edges[xx].push_back(yy);
revedges[yy].push_back(xx);
}
/// ---> compute strongly conected components <--- ///
for(int i = 1; i <= n; i++){
if(!visited[i]) dfscomputetopo(i);
}
for(int i = n; i >= 1; i--){
if(!strongcomponent[toposort[i]]){
strongcomponent[0]++;
dfsmarkcomponents(toposort[i]);
}
}
/// ---> now we have a much simpler graph <--- ///
for(int i = 1, node; i <= n; i++){
node = nodescc[i]; lastt[0] = strongcomponent[node];
arrynodes[++arrynodes[0]] = node;
lastt[strongcomponent[node]] = lastt[0];
for(auto nxt : edges[i]){
if(lastt[strongcomponent[nxt]] == lastt[0]){ continue; }
edgescomp[strongcomponent[node]].push_back(strongcomponent[nxt]);
lastt[strongcomponent[nxt]] = lastt[0];
}
if(i == n || strongcomponent[node] != strongcomponent[nodescc[i + 1]]){
for(int j = 1; j <= arrynodes[0]; j++){
node = arrynodes[j];
for(auto nxt : revedges[node]){
if(lastt[strongcomponent[nxt]] == lastt[0]){ continue; }
revedgescomp[strongcomponent[node]].push_back(strongcomponent[nxt]);
lastt[strongcomponent[nxt]] = lastt[0];
}
}
arrynodes[0] = 0;
}
}
/**for(int i = 1; i <= n; i++){
lastt[0]++; ///simplfy graph :D
for(auto nxt : edges[i]){
if(strongcomponent[i] == strongcomponent[nxt]){ continue; }
edgescomp[strongcomponent[i]].push_back(strongcomponent[nxt]);
lastt[strongcomponent[nxt]] = lastt[0];
}
for(auto nxt : revedges[i]){
if(strongcomponent[i] == strongcomponent[nxt]){ continue; }
if(lastt[strongcomponent[nxt]] == lastt[0]){ continue; }
revedgescomp[strongcomponent[i]].push_back(strongcomponent[nxt]);
}
}**/
/// ---> answer queries <--- ///
in>>nrq;
for(int itq = 1; itq <= nrq; itq++){
in>>xx>>yy;
queries[strongcomponent[xx]].push_back(make_pair(strongcomponent[yy], itq));
}
for(int comp = 1; comp <= strongcomponent[0]; comp++){
if(!queries[comp].size()){ continue; }
solvestronglycomponent(comp);
}
for(int itq = 1; itq <= nrq; itq++){
out<<answer[itq]<<"\n";
}
return 0;
}