├── 01-Find Center of Star Graph.cpp ├── 02-Maximal Network Rank.cpp ├── 03-Minimum Degree of a Connected Trio in a Graph.cpp ├── 04-Snakes and Ladder Game.cpp ├── 05-Message Route.cpp ├── 06-Word Ladder.cpp ├── 07-Valid Bfs.cpp ├── 08-Keys and Rooms.cpp ├── 09-Largest Island.cpp ├── 10-Astronaut Pairs.cpp ├── 11-Reconstruct Itinerary.cpp ├── 12-Cycle Detection in Undirected Graph.cpp ├── 13-Directed Graph Cycle Detection.cpp ├── 14-Course Schedule.cpp ├── 15-Is Graph Bipartite.cpp ├── 16-Detecting an Odd Length Cycle.cpp ├── 17-Detect Cycles in Grid.cpp ├── 18-Shortest Cycle in Undirected Graph.cpp ├── 19-All Paths From Source to Target.cpp ├── 20-Course Schedule II.cpp ├── 21-Largest Color Value in a Directed Graph.cpp ├── 22-Game Routes.cpp ├── 23-Disjoint Set Union.cpp ├── 24-Forest Detection.cpp ├── 25-Useless Connection.cpp ├── 26-Communication Between Towers.cpp ├── 27-Make Network Connected.cpp ├── 28-Special Paths.cpp ├── 29-Minimum Spanning Cost.cpp ├── 30-Connect All.cpp ├── 31-Remove Maximum Number of Edges.cpp ├── 32-Build Roads.cpp ├── 33-Find Critical and Pseudo-Critical Edges in MST.cpp ├── 34-Dijkstra.cpp ├── 35-Delay Time in Network.cpp ├── 36-Shortest Grid Path.cpp ├── 37-Cheapest Flight Within K Stops.cpp ├── 38-City With the Smallest Number of Neighbours at a Threshold Distance.cpp ├── 39-Travel by Car.cpp ├── 40-Shortest Superstring.cpp ├── 41-Number of Islands.cpp ├── 42-Flood Fill.cpp ├── 43-Number of Closed Islands.cpp ├── 44-Border Coloring.cpp ├── 45-Make Largest Island.cpp ├── 46-Rotting Oranges.cpp ├── 47-Shortest Bridge.cpp ├── 48-Highest Peak.cpp ├── 49-Minimum Height Trees.cpp ├── 50-Minimum Cost to Make Valid Path in a Grid.cpp ├── 51-Bob and Destructive Mind.cpp ├── 52-Fault in a Network.cpp ├── 53-Connected Cities.cpp ├── 54-GCD on Directed Path.cpp ├── 55-Subtree Problem.cpp ├── 56-Path on Tree.cpp ├── 57-Cut'em All!.cpp ├── 58-Tree Diameter.cpp ├── 59-Tree Distances.cpp ├── 60-Path Queries.cpp ├── 61-Subtree Queries.cpp ├── 62-Tree Queries.cpp ├── 63-Count Descendants.cpp ├── 64-New Year Tree.cpp ├── 65-Lowest Common Ancestor.cpp ├── 66-Distance Queries.cpp ├── 67-Path Xor.cpp ├── 68-A maximum Path.cpp ├── 69-Xor Distances.cpp ├── 70-Distance Sum.cpp ├── 71-Maximum White Subtree.cpp ├── 72-Choosing Capital for Treeland.cpp ├── 73-Distance in tree.cpp ├── 74-Tree with Maximum Cost.cpp ├── 75-Maximum Students Taking Exam.cpp ├── 76-Download Speed.cpp ├── 77-Count Pair of Nodes.cpp ├── 78-Longest Increasing Path.cpp ├── 79-Holiday Accommodation.cpp ├── 80-Distinct Colors.cpp └── README.md /01-Find Center of Star Graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define maxn 100001 5 | 6 | int findCenter(vector> edges) { 7 | vectordeg(maxn); 8 | int n=edges.size(),x,y; 9 | sets; 10 | for(int i=0;i 2 | using namespace std; 3 | 4 | int maximalNetworkRank(int n, vector> roads) { 5 | vectordeg(n); 6 | vector>edges(n,vector(n)); 7 | for(int i=0;i 2 | using namespace std; 3 | 4 | int minTrioDegree(int n, vector> edges) { 5 | int ans=1e9; 6 | int v[n+1][n+1]; 7 | memset(v,0,sizeof(v)); 8 | int deg[n+1]; 9 | memset(deg,0,sizeof(deg)); 10 | for(int i=0;i 2 | using namespace std; 3 | 4 | class Graph{ 5 | list *l; 6 | int V; 7 | 8 | public: 9 | Graph(int V){ 10 | this->V = V; 11 | l = new list[V+1]; 12 | } 13 | void addEdge(int u,int v){ 14 | l[u].push_back(v); 15 | } 16 | 17 | int minCostBFS(int src,int dest){ 18 | queue q; 19 | vector visited(V,false); 20 | vector dist(V,0); 21 | 22 | q.push(src); 23 | visited[src] = true; 24 | dist[src] = 0; 25 | 26 | while(!q.empty()){ 27 | int f = q.front(); 28 | q.pop(); 29 | 30 | for(int nbr : l[f]){ 31 | if(!visited[nbr]){ 32 | q.push(nbr); 33 | visited[nbr] = true; 34 | dist[nbr] = dist[f] + 1; 35 | } 36 | } 37 | } 38 | return dist[dest]; 39 | } 40 | 41 | }; 42 | 43 | 44 | 45 | int min_dice_throws(int n,vector > snakes, vector > ladders){ 46 | vector board(n+1,0); 47 | 48 | //board to graph conversion 49 | for(auto sp: snakes){ 50 | int s = sp.first; 51 | int e = sp.second; 52 | board[s] = e - s; 53 | } 54 | 55 | for(auto lp: ladders){ 56 | int s = lp.first; 57 | int e = lp.second; 58 | board[s] = e - s; 59 | } 60 | 61 | //Graph 62 | Graph g(n+1); 63 | for(int u=1;u 2 | using namespace std; 3 | 4 | int messageRoute(int n, vector>edges) 5 | { 6 | vector>v(n+1); 7 | int x,y,val,val1; 8 | for(int i=0;idis(n+1,1e9); 15 | queueq; 16 | vectorvisit(n+1); 17 | q.push(1); 18 | dis[1]=1; 19 | visit[1]=1; 20 | while(!q.empty()) 21 | { 22 | x=q.front(); 23 | q.pop(); 24 | for(auto itr:v[x]) 25 | { 26 | if(!visit[itr]) 27 | { 28 | visit[itr]=1; 29 | q.push(itr); 30 | } 31 | if(dis[itr]>dis[x]+1) 32 | { 33 | dis[itr]=dis[x]+1; 34 | } 35 | } 36 | } 37 | if(dis[n]==(int)1e9) 38 | { 39 | return -1; 40 | } 41 | return dis[n]; 42 | } -------------------------------------------------------------------------------- /06-Word Ladder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int ladderLength(string beginWord, string endWord, vector wordList) { 5 | unordered_sets; 6 | for(auto itr:wordList) 7 | { 8 | s.insert(itr); 9 | } 10 | queueq; 11 | int ans=0; 12 | q.push(beginWord); 13 | while(!q.empty()) 14 | { 15 | ans++; 16 | vectorv; 17 | int n=q.size(); 18 | for(int i=0;i 2 | using namespace std; 3 | 4 | bool validBfs(int n, vector sequence , vector> edges) 5 | { 6 | int x,y,val,val1; 7 | vector>v(n+1); 8 | vectorvisit(n+1); 9 | for(int i=0;iq; 16 | q.push(1); 17 | visit[1]=1; 18 | y=1; 19 | int flag=0; 20 | while(q.size()) 21 | { 22 | x=q.front(); 23 | q.pop(); 24 | sets; 25 | for(int i=0;i 2 | using namespace std; 3 | 4 | void dfs(int x,vector>&v, vector& visit) 5 | { 6 | visit[x]=1; 7 | for(auto itr:v[x]) 8 | { 9 | if(visit[itr]==0) 10 | { 11 | dfs(itr,v,visit); 12 | } 13 | } 14 | } 15 | bool canVisitAllRooms(vector> rooms) { 16 | int n=rooms.size(); 17 | vectorvisit(n); 18 | dfs(0,rooms,visit); 19 | for(int i=0;i 2 | using namespace std; 3 | 4 | int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; 5 | int maxAreaOfIsland(vector> grid) { 6 | int n=grid.size(),m=grid[0].size(),ans=0; 7 | if(n==0) 8 | { 9 | return ans; 10 | } 11 | vector>visit(n,vector(m)); 12 | for(int i=0;i>q; 21 | q.push({i,j}); 22 | visit[i][j]=1; 23 | while(!q.empty()) 24 | { 25 | pairp=q.front(); 26 | q.pop(); 27 | for(int k=0;k<4;k++) 28 | { 29 | int pos=p.first+dx[k],pos1=p.second+dy[k]; 30 | if(pos>=0 && pos1>=0 && pos 2 | using namespace std; 3 | 4 | class Graph{ 5 | list *l; 6 | int V; 7 | public: 8 | Graph(int v){ 9 | V = v; 10 | //Array of Linked List 11 | l = new list[V]; 12 | } 13 | 14 | void addEdge(int i,int j,bool bidir=true){ 15 | l[i].push_back(j); 16 | if(bidir){ 17 | l[j].push_back(i); 18 | } 19 | } 20 | int traverseHelper(int s,bool *visited){ 21 | visited[s] = true; 22 | int size = 1; 23 | 24 | //visit the neighbours of s and thier neighbours recursilvely 25 | for(int nbr:l[s]){ 26 | if(!visited[nbr]){ 27 | size += traverseHelper(nbr,visited); 28 | } 29 | } 30 | return size; 31 | } 32 | //DFS - Depth First Search O(V+E) Linear 33 | int countAstronauts(){ 34 | bool *visited = new bool[V]{0}; 35 | int ans = V*(V-1)/2; 36 | 37 | for(int i=0;i > astronauts){ 52 | //complete this method 53 | Graph g(N); 54 | 55 | for(auto edge : astronauts){ 56 | g.addEdge(edge.first,edge.second); 57 | } 58 | 59 | return g.countAstronauts(); 60 | } 61 | -------------------------------------------------------------------------------- /11-Reconstruct Itinerary.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vectorans; 5 | map>m; 6 | void dfs(string str) 7 | { 8 | while(m[str].size()>0) 9 | { 10 | auto it=m[str].begin(); 11 | string str1=*it; 12 | m[str].erase(it); 13 | dfs(str1); 14 | } 15 | ans.push_back(str); 16 | } 17 | vector findItinerary(vector> tickets) { 18 | int n=tickets.size(); 19 | ans.clear(); 20 | m.clear(); 21 | for(int i=0;i 2 | using namespace std; 3 | 4 | int flag; 5 | void dfs(int x,int p,vector&col,vector>&v) 6 | { 7 | col[x]=1; 8 | for(auto itr:v[x]) 9 | { 10 | if(itr==p) 11 | { 12 | continue; 13 | } 14 | if(col[itr]==1) 15 | { 16 | flag=1; 17 | } 18 | if(col[itr]==-1) 19 | { 20 | dfs(itr,x,col,v); 21 | } 22 | } 23 | col[x]=2; 24 | } 25 | bool solve(int n, vector > edges) { 26 | vector>v(n+1); 27 | flag=0; 28 | for(int i=0;icol(n+1,-1); 35 | for(int i=1;i<=n;i++) 36 | { 37 | if(col[i]==-1){ 38 | dfs(i,0,col,v); 39 | } 40 | } 41 | return flag==1; 42 | } -------------------------------------------------------------------------------- /13-Directed Graph Cycle Detection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool solve(int n, vector>edges) { 5 | vector>v(n+1); 6 | vectorind(n+1); 7 | int x,y; 8 | for(int i=0;itopo; 15 | queueq; 16 | for(int i=1;i<=n;i++) 17 | { 18 | if(ind[i]==0) 19 | { 20 | q.push(i); 21 | } 22 | } 23 | while(q.size()) 24 | { 25 | x=q.front(); 26 | q.pop(); 27 | topo.push_back(x); 28 | for(auto itr:v[x]) 29 | { 30 | ind[itr]--; 31 | if(ind[itr]==0) 32 | { 33 | q.push(itr); 34 | } 35 | } 36 | } 37 | return topo.size()!=n; 38 | } -------------------------------------------------------------------------------- /14-Course Schedule.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool ans; 5 | void dfs(int x,vector>&v,int col[]) 6 | { 7 | col[x]=1; 8 | for(auto itr:v[x]) 9 | { 10 | if(!col[itr]) 11 | { 12 | dfs(itr,v,col); 13 | } 14 | else 15 | { 16 | if(col[itr]==1) 17 | { 18 | ans=false; 19 | } 20 | } 21 | 22 | } 23 | col[x]=2; 24 | } 25 | bool canFinish(vector> c,int n) { 26 | ans=true; 27 | vector>v(n); 28 | for(int i=0;i 2 | using namespace std; 3 | 4 | bool isBipartite(vector> graph) { 5 | int n = graph.size(); 6 | vector colors(n, 0); 7 | queue q; 8 | 9 | for (int i = 0; i < n; i++) { 10 | if (colors[i]) continue; 11 | 12 | colors[i] = 1; 13 | q.push(i); 14 | 15 | while (!q.empty()) { 16 | int temp = q.front(); 17 | 18 | for (auto neighbor : graph[temp]) { 19 | 20 | // Color neighbor with opposite color 21 | if (!colors[neighbor]){ 22 | colors[neighbor] = -colors[temp]; 23 | q.push(neighbor); 24 | } 25 | 26 | // If the neighbor has the same color - can't bipartite. 27 | else if (colors[neighbor] == colors[temp]){ 28 | return false; 29 | } 30 | } 31 | q.pop(); 32 | } 33 | } 34 | return true; 35 | } -------------------------------------------------------------------------------- /16-Detecting an Odd Length Cycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool solve(vector> graph) 5 | { 6 | int n=graph.size(),m=graph[0].size(); 7 | vectorcol(n+1,-1); 8 | for(int i=0;iq; 13 | q.push(i); 14 | col[i]=0; 15 | while(q.size()) 16 | { 17 | int x=q.front(); 18 | q.pop(); 19 | for(auto itr:graph[x]) 20 | { 21 | if(col[itr]==-1) 22 | { 23 | col[itr]=col[x]^1; 24 | q.push(itr); 25 | } 26 | else{ 27 | if(col[itr]==col[x]) 28 | { 29 | return true; 30 | } 31 | } 32 | } 33 | } 34 | } 35 | } 36 | return false; 37 | } -------------------------------------------------------------------------------- /17-Detect Cycles in Grid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool ans; 5 | int visit[501][501],dis[501][501],dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; 6 | void dfs(int x,int y,int n,int m,int len,int pre,char ch,vector>&grid) 7 | { 8 | if(x<0 || y<0 || x>=n || y>=m || grid[x][y]!=ch) 9 | { 10 | return; 11 | } 12 | if(visit[x][y]) 13 | { 14 | if(abs(dis[x][y]-pre)>=3) 15 | { 16 | ans=true; 17 | } 18 | return; 19 | } 20 | visit[x][y]=1; 21 | dis[x][y]=len; 22 | for(int i=0;i<4;i++) 23 | { 24 | dfs(x+dx[i],y+dy[i],n,m,len+1,dis[x][y],ch,grid); 25 | } 26 | } 27 | bool containsCycle(vector> grid) { 28 | int n=grid.size(),m=grid[0].size(); 29 | memset(visit,0,sizeof(visit)); 30 | memset(dis,0,sizeof(dis)); 31 | ans=false; 32 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector> gr; 5 | int shortest_cycle(int n) 6 | { 7 | // To store length of the shortest cycle 8 | int ans = INT_MAX; 9 | 10 | // For all vertices 11 | for (int i = 1; i <= n; i++) { 12 | 13 | vector dist(n+1, (int)(1e9)); 14 | vector par(n+1, -1); 15 | dist[i] = 0; 16 | queue q; 17 | q.push(i); 18 | 19 | while (!q.empty()) { 20 | 21 | int x = q.front(); 22 | q.pop(); 23 | 24 | for (int child : gr[x]) { 25 | 26 | if (dist[child] == (int)(1e9)) { 27 | 28 | dist[child] = 1 + dist[x]; 29 | par[child] = x; 30 | q.push(child); 31 | } 32 | 33 | else if (par[x] != child and par[child] != x){ 34 | ans = min(ans, dist[x] + dist[child] + 1); 35 | } 36 | } 37 | } 38 | } 39 | 40 | if (ans == INT_MAX){ 41 | return -1; 42 | } 43 | else{ 44 | return ans; 45 | } 46 | } 47 | int solve(int n,vector> edges){ 48 | gr=vector>(n+1,vector()); 49 | for(int i=0;i 2 | using namespace std; 3 | 4 | void dfs(int x,vector>&v,int n,vector&vec,vector>&ans) 5 | { 6 | vec.push_back(x); 7 | if(x==n-1) 8 | { 9 | ans.push_back(vec); 10 | } 11 | for(auto itr:v[x]) 12 | { 13 | dfs(itr,v,n,vec,ans); 14 | } 15 | vec.pop_back(); 16 | } 17 | vector> allPathsSourceTarget(vector> graph) { 18 | int n=graph.size(); 19 | vector>ans; 20 | vectorv; 21 | dfs(0,graph,n,v,ans); 22 | return ans; 23 | } -------------------------------------------------------------------------------- /20-Course Schedule II.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool canFinish(vector> prerequisites, int n) { 5 | vector> G(n); 6 | vector degree(n, 0), bfs; 7 | for (auto& e : prerequisites) 8 | G[e[1]].push_back(e[0]), degree[e[0]]++; 9 | for (int i = 0; i < n; ++i) if (!degree[i]) bfs.push_back(i); 10 | for (int i = 0; i < bfs.size(); ++i) 11 | for (int j: G[bfs[i]]) 12 | if (--degree[j] == 0) bfs.push_back(j); 13 | return bfs.size() == n; 14 | } 15 | -------------------------------------------------------------------------------- /21-Largest Color Value in a Directed Graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int largestPathValue(string colors, vector> edges) { 5 | int n=colors.size(); 6 | vector>cnt(n,vector(26)); 7 | vector>v(n+1); 8 | vectorin(n+1); 9 | for(int i=0;iq; 16 | for(int i=0;itopo; 26 | while(q.size()) 27 | { 28 | int x=q.front(); 29 | q.pop(); 30 | topo.push_back(x); 31 | for(int i=0;i<26;i++) 32 | { 33 | ans=max(ans,cnt[x][i]); 34 | } 35 | for(auto itr:v[x]) 36 | { 37 | for(int i=0;i<26;i++) 38 | { 39 | cnt[itr][i]=max(cnt[itr][i],cnt[x][i]+ (colors[itr]-'a'==i)); 40 | } 41 | in[itr]--; 42 | if(in[itr]==0) 43 | { 44 | q.push(itr); 45 | } 46 | } 47 | } 48 | return topo.size()==n?ans:-1; 49 | } -------------------------------------------------------------------------------- /22-Game Routes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define mod 1000000007 4 | 5 | int gameRoutes(int n, vector> teleporters) 6 | { 7 | long long x,y; 8 | vector>v(n+1); 9 | vectorind(n+1); 10 | vectordp(n+1); 11 | for(int i=0;iq; 18 | vectortopo; 19 | for(int i=1;i<=n;i++) 20 | { 21 | if(ind[i]==0) 22 | { 23 | q.push(i); 24 | } 25 | } 26 | while(q.size()) 27 | { 28 | x=q.front(); 29 | q.pop(); 30 | topo.push_back(x); 31 | for(auto itr:v[x]) 32 | { 33 | ind[itr]--; 34 | if(ind[itr]==0) 35 | { 36 | q.push(itr); 37 | } 38 | } 39 | } 40 | dp[1]=1; 41 | for(auto itr:topo) 42 | { 43 | for(auto it:v[itr]) 44 | { 45 | dp[it]=(dp[it]+dp[itr])%mod; 46 | } 47 | } 48 | return dp[n]; 49 | } -------------------------------------------------------------------------------- /23-Disjoint Set Union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | #define maxn 100001 5 | int find(int x,vector&visit) 6 | { 7 | while(x!=visit[x]) 8 | { 9 | return visit[x]=find(visit[x],visit); 10 | } 11 | return x; 12 | } 13 | void Union(int x,int y,vector&visit,vector&sz) 14 | { 15 | int val=find(x,visit),val1=find(y,visit); 16 | if(val==val1) 17 | { 18 | return; 19 | } 20 | if(sz[val]>sz[val1]) 21 | { 22 | swap(val,val1); 23 | } 24 | visit[val]=val1; 25 | sz[val1]+=sz[val]; 26 | } 27 | vector DSU(vector>query) 28 | { 29 | int n=query.size(); 30 | vectorvisit(maxn),sz(maxn,1); 31 | iota(visit.begin(),visit.end(),0); 32 | vectorans; 33 | for(int i=0;i 2 | using namespace std; 3 | 4 | #define maxn 100001 5 | vectorvisit,sz; 6 | int find(int x) 7 | { 8 | if(visit[x]!=x) 9 | { 10 | return visit[x]=find(visit[x]); 11 | } 12 | return x; 13 | } 14 | void Union(int x,int y) 15 | { 16 | int val=find(x),val1=find(y); 17 | if(val==val1) 18 | { 19 | return; 20 | } 21 | if(sz[val]>sz[val1]) 22 | { 23 | swap(val,val1); 24 | } 25 | visit[val]=val1; 26 | sz[val1]+=sz[val]; 27 | } 28 | bool solve(vector> edges) { 29 | visit.resize(maxn); 30 | iota(visit.begin(),visit.end(),0); 31 | sz.assign(maxn,1); 32 | int n=edges.size(); 33 | for(int i=0;i 2 | using namespace std; 3 | 4 | int visit[1001]; 5 | int find(int x) 6 | { 7 | if(x!=visit[x]) 8 | { 9 | return visit[x]=find(visit[x]); 10 | } 11 | return x; 12 | } 13 | void Union(int x,int y) 14 | { 15 | int val=find(x),val1=find(y); 16 | visit[val]=val1; 17 | } 18 | vector findUselessConnection(vector> edges) { 19 | int n=edges.size(); 20 | for(int i=0;i<1001;i++) 21 | { 22 | visit[i]=i; 23 | } 24 | vectorans; 25 | for(int i=0;i 2 | using namespace std; 3 | 4 | void dfs(int x,int y,int n,int m,vector>&matrix,vector>&visit) 5 | { 6 | if(visit[x][y]) 7 | { 8 | return; 9 | } 10 | visit[x][y]=1; 11 | for(int i=0;i> matrix) { 27 | int n=matrix.size(); 28 | int m=matrix[0].size(),ans=0; 29 | vector>visit(n+1,vector(m+1)); 30 | for(int i=0;i 2 | using namespace std; 3 | 4 | int find(int x,vector&visit) 5 | { 6 | if(x!=visit[x]) 7 | { 8 | return visit[x]=find(visit[x],visit); 9 | } 10 | return x; 11 | } 12 | void Union(int x,int y,vector&visit,vector&sz) 13 | { 14 | int val=find(x,visit),val1=find(y,visit); 15 | if(val==val1) 16 | { 17 | return; 18 | } 19 | if(sz[val]>sz[val1]) 20 | { 21 | swap(val,val1); 22 | } 23 | visit[val]=val1; 24 | sz[val1]+=sz[val]; 25 | } 26 | int makeConnected(int n, vector> connections) { 27 | vectorvisit(n),sz(n); 28 | iota(visit.begin(),visit.end(),0); 29 | sz.assign(n,1); 30 | int cnt=0,extra=0; 31 | for(int i=0;i 2 | using namespace std; 3 | 4 | vectormarked,sz; 5 | int find(int x) 6 | { 7 | if(marked[x]!=x) 8 | { 9 | return marked[x]=find(marked[x]); 10 | } 11 | return x; 12 | } 13 | void Union(int x,int y) 14 | { 15 | int val=find(x),val1=find(y); 16 | if(val==val1) 17 | { 18 | return; 19 | } 20 | if(sz[val]>sz[val1]) 21 | { 22 | swap(val,val1); 23 | } 24 | marked[val]=val1; 25 | sz[val1]+=sz[val]; 26 | } 27 | int specialPath(int n, vector a, vector> edges,int start, int end) 28 | { 29 | int x,y,val,flag; 30 | int l=1,r=1e9,mid,ans=1e9; 31 | marked=vector(n+1); 32 | while(l<=r) 33 | { 34 | mid=(l+r)/2; 35 | iota(marked.begin(),marked.end(),0); 36 | sz.assign(n+1,1); 37 | for(int i=0;i 2 | using namespace std; 3 | 4 | vectorvisit,sz; 5 | bool comp(const vector& arr1, const vector& arr2) 6 | { 7 | return arr1[2]&visit) 10 | { 11 | if(x!=visit[x]) 12 | { 13 | return visit[x]=find(visit[x],visit); 14 | } 15 | return x; 16 | } 17 | void Union(int x,int y,vector&visit, vector&sz) 18 | { 19 | int val=find(x,visit),val1=find(y,visit); 20 | if(val==val1) 21 | { 22 | return; 23 | } 24 | if(sz[val]>sz[val1]) 25 | { 26 | swap(val,val1); 27 | } 28 | visit[val]=val1; 29 | sz[val1]+=sz[val]; 30 | } 31 | int MST(int n, vector> edges) 32 | { 33 | int x,y,val; 34 | visit.resize(n+1); 35 | iota(visit.begin(),visit.end(),0); 36 | sz.assign(n+1,1); 37 | sort(edges.begin(),edges.end(),comp); 38 | int ans=0; 39 | for(int i=0;i 2 | using namespace std; 3 | 4 | int par[1005],sz[1005]; 5 | 6 | int findpar(int u){ 7 | if(u==par[u]){return u;} 8 | return par[u] = findpar(par[u]); 9 | } 10 | bool fmerge(int u, int v){ 11 | int pu=findpar(u),pv=findpar(v); 12 | if(pu==pv){return 0;} 13 | if(sz[pu]> points) { 21 | for(int i=0;i<=1000;i++){ 22 | par[i]=i;sz[i]=1; 23 | } 24 | vector > > edges; 25 | int n=points.size(); 26 | for(int i=0;i 2 | using namespace std; 3 | 4 | int find(int x,vector&visit) 5 | { 6 | if(x!=visit[x]) 7 | { 8 | return visit[x]=find(visit[x],visit); 9 | } 10 | return x; 11 | } 12 | void Union(int x,int y,vector&visit,vector&sz) 13 | { 14 | int val=find(x,visit),val1=find(y,visit); 15 | if(val==val1) 16 | { 17 | return ; 18 | } 19 | if(sz[val]>sz[val1]) 20 | { 21 | swap(val,val1); 22 | } 23 | visit[val]=val1; 24 | sz[val1]+=sz[val]; 25 | } 26 | int maxNumEdgesToRemove(int n, vector> edges) { 27 | vectorvisit1(n+1),visit2(n+1),sz1(n+1,1),sz2(n+1,1); 28 | iota(visit1.begin(),visit1.end(),0); 29 | iota(visit2.begin(),visit2.end(),0); 30 | vector>v[3]; 31 | for(int i=0;i 2 | using namespace std; 3 | #define maxn 100001 4 | #define pb push_back 5 | vectorpar(maxn),sz(maxn,1); 6 | int find(int x) 7 | { 8 | if(x!=par[x]) 9 | { 10 | return par[x]=find(par[x]); 11 | } 12 | return x; 13 | } 14 | void Union(int x,int y) 15 | { 16 | int val=find(x),val1=find(y); 17 | if(val==val1) 18 | { 19 | return; 20 | } 21 | if(sz[val]>sz[val1]) 22 | { 23 | swap(val,val1); 24 | } 25 | par[val]=val1; 26 | sz[val1]+=sz[val]; 27 | } 28 | long long buildRoads(vector>Coordinates){ 29 | int n=Coordinates.size(); 30 | long long p,q; 31 | iota(par.begin(),par.end(),0); 32 | vector>x,y; 33 | for(long long i=0;i>edges; 42 | for(int i=1;i 2 | using namespace std; 3 | 4 | // DSU 5 | 6 | vector par, size; 7 | 8 | void init(int n) 9 | { 10 | for(int i=0; i> edges, int avoid) 44 | { 45 | int cost = 0; 46 | 47 | for(auto e: edges) 48 | { 49 | int id = e[3]; 50 | if(id == avoid) 51 | continue; 52 | 53 | int p1 = Find(e[0]); 54 | int p2 = Find(e[1]); 55 | if(p1 == p2) 56 | continue; 57 | 58 | Union(p1, p2); 59 | cost += e[2]; 60 | } 61 | 62 | return cost; 63 | } 64 | 65 | // Sort according to weight 66 | 67 | bool cmp(vector a, vector b) 68 | { 69 | return a[2]> findCriticalAndPseudoCriticalEdges(int n, vector> edges) 75 | { 76 | par.resize(n); 77 | size.resize(n); 78 | 79 | vector critical, pseudo; 80 | 81 | for(int i=0; iminCost or Find(e[0])!=Find(e[1])) 98 | { 99 | critical.push_back(e[3]); 100 | continue; 101 | } 102 | 103 | // Else check if including the edge results in BST, then it is pseudo-critical else not useful edge 104 | init(n); 105 | 106 | // Include this edge forcefully 107 | Union(e[0], e[1]); 108 | cost = e[2]; 109 | 110 | cost += MST(edges, e[3]); 111 | 112 | if(cost == minCost) 113 | pseudo.push_back(e[3]); 114 | } 115 | 116 | vector> ans; 117 | sort(critical.begin(),critical.end()); 118 | sort(pseudo.begin(),pseudo.end()); 119 | ans.push_back(critical); 120 | ans.push_back(pseudo); 121 | 122 | return ans; 123 | } 124 | -------------------------------------------------------------------------------- /34-Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define fi first 4 | #define se second 5 | #define pb push_back 6 | const int inf = 1e9; 7 | class Dijkstra 8 | { 9 | public: 10 | vector dis,par; 11 | vector>> adj; 12 | Dijkstra(int n,vector>> A) 13 | { 14 | dis.resize(n+1); 15 | par.resize(n+1,0); 16 | for(int i=1;i<=n;++i) 17 | dis[i]=inf; 18 | adj = A; 19 | } 20 | 21 | void find_dis(int root) 22 | { 23 | set> s; 24 | s.insert({0,root}); 25 | dis[root]=0; 26 | par[root]=root; 27 | while(!s.empty()) 28 | { 29 | pair p=*s.begin(); 30 | s.erase(p); 31 | for(auto i:adj[p.se]) 32 | { 33 | if(p.fi+i.fi find_path(int root) 45 | { 46 | vector path; 47 | int p=root; 48 | while(p!=1) 49 | { 50 | path.pb(p); 51 | p=par[p]; 52 | } 53 | path.pb(1); 54 | reverse(path.begin(),path.end()); 55 | return path; 56 | } 57 | }; 58 | 59 | vector shortestPath(vector> roads,int n) 60 | { 61 | vector>> adj(n+1); 62 | for(auto i : roads) 63 | { 64 | adj[i[0]].pb({i[2],i[1]}); 65 | adj[i[1]].pb({i[2],i[0]}); 66 | } 67 | 68 | Dijkstra d(n,adj); 69 | d.find_dis(1); 70 | return d.find_path(n); 71 | } -------------------------------------------------------------------------------- /35-Delay Time in Network.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int networkDelayTime(vector> times, int N, int K) { 5 | // build graph 6 | vector > > graph(N+1); 7 | for (auto edge : times) { 8 | int fr_node = edge[0]; 9 | int to_node = edge[1]; 10 | int cost = edge[2]; 11 | graph[fr_node].push_back(make_pair(cost, to_node)); 12 | } 13 | vector dist(N+1, INT_MAX); 14 | priority_queue, vector>, greater>> pq; 15 | dist[K] = 0; 16 | pq.push(make_pair(0, K)); 17 | while (!pq.empty()) { 18 | pair x = pq.top(); 19 | pq.pop(); 20 | for (auto neighbor : graph[x.second]) { 21 | int ar = dist[x.second] + neighbor.first; 22 | if (ar < dist[neighbor.second]) { 23 | dist[neighbor.second] = ar; 24 | pq.push(make_pair(ar, neighbor.second)); 25 | } 26 | } 27 | } 28 | int max_time = INT_MIN; 29 | for (int i = 1; i < dist.size(); ++i) { 30 | if (max_time < dist[i]) { 31 | max_time = dist[i]; 32 | } 33 | } 34 | 35 | return max_time == INT_MAX? -1 : max_time; 36 | } -------------------------------------------------------------------------------- /36-Shortest Grid Path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | //dijkshtras 5 | class Node{ 6 | public: 7 | int x,y; 8 | int dist; 9 | 10 | Node(int x,int y,int dist){ 11 | this->x = x; 12 | this->y = y; 13 | this->dist = dist; 14 | } 15 | 16 | }; 17 | 18 | //comparator should return boolean value, indicating whether the element passed as first argument is considered to go before the second in the specific strict weak ordering 19 | class Compare{ 20 | public: 21 | bool operator()(Node a,Node b){ 22 | return a.dist <= b.dist; 23 | } 24 | 25 | }; 26 | 27 | int shortest_path(vector > grid){ 28 | 29 | //----------------///// 30 | int m = grid.size(); 31 | int n = grid[0].size(); 32 | int i = 0; 33 | int j = 0; 34 | 35 | vector > dist(m+1,vector(n+1,INT_MAX)); 36 | 37 | dist[i][j] = grid[0][0]; 38 | set s; 39 | s.insert(Node(i,j,dist[0][0])); 40 | 41 | int dx[] = {0,0,1,-1}; 42 | int dy[] = {1,-1,0,0}; 43 | 44 | while(!s.empty()){ 45 | //get the node that is having smallest dist 46 | auto it = s.begin(); 47 | int cx = it->x; 48 | int cy = it->y; 49 | int cd = it->dist; 50 | s.erase(it); 51 | 52 | //update the neigbours of this node and push them in the set 53 | for(int k=0;k<4;k++){ 54 | int nx = cx + dx[k]; 55 | int ny = cy + dy[k]; 56 | if(nx>=0 and nx=0 and ny cd + grid[nx][ny]){ 57 | //remove the old node from the set 58 | Node temp(nx,ny,dist[nx][ny]); 59 | if(s.find(temp)!=s.end()){ 60 | s.erase(s.find(temp)); 61 | } 62 | //insert the new node in the set 63 | int nd = grid[nx][ny] + cd; 64 | dist[nx][ny] = nd; 65 | s.insert(Node(nx,ny,nd)); 66 | } 67 | } 68 | 69 | } 70 | for(int i=0;i 2 | using namespace std; 3 | 4 | int findCheapestPrice(int n, vector> flights, int src, int dst, int k) { 5 | vector dist( n, 1000000000 ); 6 | dist[src] = 0; 7 | 8 | // Run only K+1 times since we want shortest distance in atmost k stops 9 | for( int i=0; i <= k; i++ ) { 10 | vector tmp( dist ); 11 | for( auto flight : flights ) { 12 | if( dist[ flight[0] ] != INT_MAX ) { 13 | tmp[ flight[1] ] = min( tmp[flight[1]], dist[ flight[0] ] + flight[2] ); 14 | } 15 | } 16 | dist = tmp; 17 | } 18 | return dist[dst] == INT_MAX ? -1 : dist[dst]; 19 | } -------------------------------------------------------------------------------- /38-City With the Smallest Number of Neighbours at a Threshold Distance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define inf 1e9 4 | 5 | int findTheCity(int n, vector> edges, int distanceThreshold) { 6 | vector>dis(n+1,vector(n+1,inf)); 7 | for(int i=0;i dis[j][i]+ dis[i][k]) 24 | { 25 | dis[j][k]=dis[j][i]+dis[i][k]; 26 | } 27 | } 28 | } 29 | } 30 | vectorcnt(n); 31 | int val=inf; 32 | for(int i=0;i 2 | using namespace std; 3 | #define inf 1e9 4 | 5 | vector travelByCar(int n,int l, vector>edges ,vector> queries) 6 | { 7 | vector>dis(n+1,vector(n+1,inf)),fuel(n+1,vector(n+1,inf)); 8 | int x,y,val; 9 | for(int i=0;idis[j][i]+dis[i][k]) 28 | { 29 | dis[j][k]=dis[j][i]+dis[i][k]; 30 | } 31 | } 32 | } 33 | } 34 | for(int i=0;ifuel[j][i]+fuel[i][k]) 55 | { 56 | fuel[j][k]=fuel[j][i]+fuel[i][k]; 57 | } 58 | } 59 | } 60 | } 61 | vectorans; 62 | for(int i=0;i 2 | using namespace std; 3 | 4 | //Travelling salesman problem 5 | //cost moving from one string to another is nonoverlapping string between them 6 | int n; 7 | string solve(int pos,int val,vector>&dp,vector>&v) 8 | { 9 | if(val==0) 10 | { 11 | return ""; 12 | } 13 | if(dp[pos][val].size()!=0) 14 | { 15 | return dp[pos][val]; 16 | } 17 | string ans=""; 18 | for(int i=0;istr.size()?str:ans; 27 | } 28 | else{ 29 | ans=str; 30 | } 31 | } 32 | } 33 | return dp[pos][val]=ans; 34 | } 35 | string shortestSuperstring(vector words) { 36 | n=words.size(); 37 | vector>v(n,vector(n,"")); 38 | for(int i=0;i>dp(n,vector(val,"")); 69 | for(int i=0;istr.size()?str:ans; 76 | } 77 | else{ 78 | ans=str; 79 | } 80 | } 81 | return ans; 82 | } -------------------------------------------------------------------------------- /41-Number of Islands.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void dfs(int x,int y,int n,int m,vector>&v,vector>&visit) 5 | { 6 | if(x<0 || y<0 || x>=n || y>=m || v[x][y]=='0') 7 | { 8 | return; 9 | } 10 | if(visit[x][y]) 11 | { 12 | return; 13 | } 14 | visit[x][y]=1; 15 | dfs(x+1,y,n,m,v,visit); 16 | dfs(x-1,y,n,m,v,visit); 17 | dfs(x,y+1,n,m,v,visit); 18 | dfs(x,y-1,n,m,v,visit); 19 | } 20 | int numIslands(vector> grid) { 21 | int n=grid.size (); 22 | if(n==0) 23 | { 24 | return 0; 25 | } 26 | int m=grid[0].size (); 27 | vector>visit(n,vector(m)); 28 | int ans=0; 29 | cout< 2 | using namespace std; 3 | 4 | int x[4]={-1,0,1,0}; 5 | int y[4]={0,1,0,-1}; 6 | void solve(int sr,int sc,int m,int n,int newColor,vector>& image,int oldcolor) 7 | { 8 | if(sr<0 || sc<0 || sr>=m || sc>=n || oldcolor!=image[sr][sc]){ 9 | return; 10 | } 11 | image[sr][sc]=newColor; 12 | for(int i=0;i<4;i++){ 13 | solve(sr+x[i],sc+y[i],m,n,newColor,image,oldcolor); 14 | } 15 | } 16 | vector> floodFill(vector> image, int sr, int sc, int newColor){ 17 | if(newColor==image[sr][sc]){ 18 | return image; 19 | } 20 | int m=image.size(); 21 | int n=image[0].size(); 22 | int oldcolor=image[sr][sc]; 23 | solve(sr,sc,m,n,newColor,image,oldcolor); 24 | return image; 25 | } -------------------------------------------------------------------------------- /43-Number of Closed Islands.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int fill(vector>& g, int i, int j) { 5 | if (i < 0 || j < 0 || i >= g.size() || j >= g[i].size() || g[i][j]){ 6 | return 0; 7 | } 8 | return (g[i][j] = 1) + fill(g, i + 1, j) + fill(g, i, j + 1) + fill(g, i - 1, j) + fill(g, i, j - 1); 9 | } 10 | int closedIsland(vector> g) { 11 | for (int i = 0; i < g.size(); ++i){ 12 | for (int j = 0; j < g[i].size(); ++j){ 13 | if (i * j == 0 || i == g.size() - 1 || j == g[i].size() - 1){ 14 | fill(g, i, j); 15 | } 16 | } 17 | } 18 | int res=0; 19 | for (int i = 0; i < g.size(); ++i){ 20 | for (int j = 0; j < g[i].size(); ++j){ 21 | res += fill(g, i, j) > 0; 22 | } 23 | } 24 | return res; 25 | } -------------------------------------------------------------------------------- /44-Border Coloring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void dfs(vector>& g, int r, int c, int cl) { 5 | if (r < 0 || c < 0 || r >= g.size() || c >= g[r].size() || g[r][c] != cl){ 6 | return; 7 | } 8 | g[r][c] = -cl; 9 | dfs(g, r - 1, c, cl); 10 | dfs(g, r + 1, c, cl); 11 | dfs(g, r, c - 1, cl); 12 | dfs(g, r, c + 1, cl); 13 | if (r > 0 && r < g.size() - 1 && c > 0 && c < g[r].size() - 1 && cl == abs(g[r - 1][c]) && cl == abs(g[r + 1][c]) && cl == abs(g[r][c - 1]) && cl == abs(g[r][c + 1])){ 14 | g[r][c] = cl; 15 | } 16 | } 17 | 18 | vector> colorBorder(vector> grid, int r0, int c0, int color) { 19 | dfs(grid, r0, c0, grid[r0][c0]); 20 | for (auto i = 0; i < grid.size(); ++i){ 21 | for (auto j = 0; j < grid[i].size(); ++j){ 22 | grid[i][j] = grid[i][j] < 0 ? color : grid[i][j]; 23 | } 24 | } 25 | return grid; 26 | } -------------------------------------------------------------------------------- /45-Make Largest Island.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int cnt,n,dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; 5 | vector>vec; 6 | void dfs(int x,int y,vector>&grid, vector>&visit) 7 | { 8 | if(x<0 || y<0 || x>=n || y>=n || grid[x][y]==0 || visit[x][y]==1) 9 | { 10 | return; 11 | } 12 | cnt++; 13 | visit[x][y]=1; 14 | vec.push_back({x,y}); 15 | dfs(x+1,y,grid,visit); 16 | dfs(x-1,y,grid,visit); 17 | dfs(x,y+1,grid,visit); 18 | dfs(x,y-1,grid,visit); 19 | } 20 | int largestIsland(vector> grid) { 21 | n=grid.size(); 22 | vector>visit(n+1,vector(n+1)); 23 | vector>temp(n+1,vector(n+1)),ind(n+1,vector(n+1)); 24 | int num=1; 25 | for(int i=0;is; 52 | for(int k=0;k<4;k++) 53 | { 54 | int x=i+dx[k],y=j+dy[k]; 55 | if(x>=0 && y>=0 && x 2 | using namespace std; 3 | 4 | int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; 5 | int orangesRotting(vector> grid) { 6 | int n=grid.size(),m=grid[0].size(); 7 | queue>q; 8 | vector>visit(n,vector(m)),dist(n,vector(m,INT_MAX)); 9 | for(int i=0;ip=q.front(); 24 | q.pop(); 25 | for(int i=0;i<4;i++) 26 | { 27 | int x=p.first+dx[i],y=p.second+dy[i]; 28 | if(x>=0 && x=0 && y 2 | using namespace std; 3 | 4 | vector>v; 5 | void dfs(int x,int y,int n,vector>&a,vector>&visit) 6 | { 7 | if(x<0 || y<0 || x>=n ||y>=n || a[x][y]==0) 8 | { 9 | return; 10 | } 11 | if(visit[x][y]) 12 | { 13 | return; 14 | } 15 | visit[x][y]=1; 16 | v.push_back({x,y}); 17 | dfs(x+1,y,n,a,visit); 18 | dfs(x-1,y,n,a,visit); 19 | dfs(x,y+1,n,a,visit); 20 | dfs(x,y-1,n,a,visit); 21 | } 22 | int shortestBridge(vector> a) { 23 | int n=a.size(),val=0; 24 | v.clear(); 25 | vector>visit(n,vector(n)); 26 | for(int i=0;i>q; 43 | vector>visit1(n,vector(n)),dis(n,vector(n)); 44 | int ans=INT_MAX,dx[4]={1,-1,0,0},dy[4]={0,0,1,-1}; 45 | for(auto itr:v) 46 | { 47 | q.push({itr.first,itr.second}); 48 | visit1[itr.first][itr.second]=1; 49 | } 50 | while(!q.empty()) 51 | { 52 | pairp=q.front(); 53 | q.pop(); 54 | if(!visit[p.first][p.second] && a[p.first][p.second]==1) 55 | { 56 | ans=min(ans,dis[p.first][p.second]); 57 | break; 58 | } 59 | for(int i=0;i<4;i++) 60 | { 61 | int pos=p.first+dx[i],pos1=p.second+dy[i]; 62 | if(pos>=0 && pos1>=0 && pos 2 | using namespace std; 3 | 4 | int dirs[5] = {0, 1, 0, -1, 0}; 5 | vector> highestPeak(vector> w) { 6 | vector> p; 7 | int h = 1, si = w.size(), sj = w[0].size(); 8 | for (auto i = 0; i < si; ++i) 9 | for (auto j = 0; j < sj; ++j) { 10 | w[i][j] = w[i][j] == 1 ? 0 : -1; 11 | if (w[i][j] == 0) 12 | p.push_back({i, j}); 13 | } 14 | while (!p.empty()) { 15 | vector> p1; 16 | for (auto [i, j] : p) { 17 | for (int d = 0; d < 4; ++d) { 18 | int x = i + dirs[d], y = j + dirs[d + 1]; 19 | if (x >= 0 && y >= 0 && x < si && y < sj && w[x][y] == -1) { 20 | w[x][y] = h; 21 | p1.push_back({x, y}); 22 | } 23 | } 24 | } 25 | swap(p, p1); 26 | ++h; 27 | } 28 | return w; 29 | } -------------------------------------------------------------------------------- /49-Minimum Height Trees.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector findMinHeightTrees(int n, vector> edges) { 5 | //edge case 6 | if(n<2) 7 | { 8 | return {0}; 9 | } 10 | vectorans; 11 | vector>v(n+1); 12 | int x,y; 13 | vectordeg(n+1); 14 | for(int i=0;iq; 23 | for(int i=0;ivisit(n+1); 32 | while(cnt>2) 33 | { 34 | vectorvec; 35 | while(q.size()) 36 | { 37 | x=q.front(); 38 | q.pop(); 39 | cnt--; 40 | visit[x]=1; 41 | for(auto itr:v[x]) 42 | { 43 | if(!visit[itr]) 44 | { 45 | deg[itr]--; 46 | if(deg[itr]==1) 47 | { 48 | vec.push_back(itr); 49 | } 50 | } 51 | } 52 | } 53 | for(auto itr:vec) 54 | { 55 | q.push(itr); 56 | } 57 | } 58 | while(q.size()) 59 | { 60 | ans.push_back(q.front()); 61 | q.pop(); 62 | } 63 | return ans; 64 | } -------------------------------------------------------------------------------- /50-Minimum Cost to Make Valid Path in a Grid.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; 5 | int minCost(vector> grid) { 6 | int n=grid.size(),m=grid[0].size(); 7 | deque>qu; 8 | qu.push_front({0,0,0}); 9 | vector>dis(n+1,vector(m+1,1e9)); 10 | dis[0][0]=0; 11 | int ans; 12 | while(qu.size()) 13 | { 14 | arrayarr=qu.front(); 15 | int x=arr[1],y=arr[2],val=arr[0]; 16 | qu.pop_front(); 17 | if(x==n-1 && y==m-1) 18 | { 19 | ans=val; 20 | break; 21 | } 22 | for(int i=0;i<4;i++) 23 | { 24 | int p=x+dx[i],q=y+dy[i]; 25 | int dir=i+1; 26 | if(p>=0 && q>=0 && pval+flag) 34 | { 35 | if(flag) 36 | { 37 | qu.push_back({val+flag,p,q}); 38 | } 39 | else{ 40 | qu.push_front({val,p,q}); 41 | } 42 | } 43 | dis[p][q]=min(dis[p][q],val+flag); 44 | } 45 | } 46 | } 47 | return ans; 48 | } -------------------------------------------------------------------------------- /51-Bob and Destructive Mind.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector>v; 5 | vectorvisit,tin,low,ans; 6 | int timer; 7 | void dfs(int x,int p) 8 | { 9 | tin[x]=low[x]=++timer; 10 | int child=0; 11 | visit[x]=1; 12 | for(auto itr:v[x]) 13 | { 14 | if(itr==p) 15 | { 16 | continue; 17 | } 18 | if(visit[itr]==1) 19 | { 20 | low[x]=min(low[x],tin[itr]); 21 | } 22 | else{ 23 | child++; 24 | dfs(itr,x); 25 | low[x]=min(low[x],low[itr]); 26 | if(p!=-1 && tin[x]<=low[itr]) 27 | { 28 | ans[x]=1; 29 | } 30 | } 31 | } 32 | if(p==-1 && child>1) 33 | { 34 | ans[x]=1; 35 | } 36 | } 37 | vector destructiveBob(int n, vector> edges, vectorqueries) 38 | { 39 | timer=0; 40 | v=vector>(n+1,vector()); 41 | tin=vector(n+1); 42 | low=vector(n+1); 43 | ans=vector(n+1); 44 | visit=vector(n+1); 45 | int x,y,val; 46 | for(int i=0;ivec; 60 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>bridges; 5 | vectortin,low; 6 | int timer; 7 | void dfs(int x,int p,vector&visit,vector>&v) 8 | { 9 | visit[x]=1; 10 | tin[x]=low[x]=++timer; 11 | for(auto itr:v[x]) 12 | { 13 | if(itr==p) 14 | { 15 | continue; 16 | } 17 | if(visit[itr]) 18 | { 19 | low[x]=min(low[x],tin[itr]); 20 | } 21 | else{ 22 | dfs(itr,x,visit,v); 23 | low[x]=min(low[x],low[itr]); 24 | if(low[itr]>tin[x]) 25 | { 26 | bridges.push_back({x,itr}); 27 | } 28 | } 29 | } 30 | } 31 | vector> criticalConnections(int n, vector> connections) { 32 | vector>v(n+1); 33 | for(int i=0;ivisit(n+1); 44 | dfs(0,0,visit,v); 45 | return bridges; 46 | } -------------------------------------------------------------------------------- /53-Connected Cities.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool BFS(int n, unordered_map> g) { 5 | queue q; 6 | q.push(0); 7 | unordered_map vis; 8 | vis[0] = true; 9 | while (!q.empty()) { 10 | int P = q.front(); 11 | q.pop(); 12 | for (auto &c : g[P]) { 13 | if (!vis[c]) { 14 | vis[c] = true; 15 | q.push(c); 16 | } 17 | } 18 | } 19 | return vis.size() == n; 20 | } 21 | bool solve(int n, vector> roads) { 22 | unordered_map> g; 23 | for (auto &c : roads){ 24 | g[c[0]].insert(c[1]); 25 | } 26 | 27 | bool allvis = BFS(n, g); 28 | if (!allvis){ 29 | return allvis; 30 | } 31 | unordered_map> revg; 32 | for (auto &[k, v] : g) { 33 | for (auto &c : v) revg[c].insert(k); 34 | } 35 | allvis = BFS(n, revg); 36 | return allvis; 37 | } -------------------------------------------------------------------------------- /54-GCD on Directed Path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define INF 1000000009 4 | 5 | vectorA,val,comp; 6 | vector > v,rev_v,scc_v; 7 | vectorvis; 8 | int components; 9 | vector> ss; 10 | 11 | /** 12 | * Push the vertices in the stack in the decreasing order 13 | * of their finishing times. 14 | * 15 | * First DFS of the Kosaraju Algorithm 16 | **/ 17 | void dfs_0(int curr,stack&s) 18 | { 19 | vis[curr] = true; 20 | for ( int i = 0; i < (int)v[curr].size(); i++ ) { 21 | if ( vis[v[curr][i]] ) continue; 22 | dfs_0(v[curr][i],s); 23 | } 24 | s.push(curr); 25 | } 26 | 27 | void dfs_1(int curr) 28 | { 29 | vis[curr] = true; 30 | comp[curr] = components; 31 | val[components] = __gcd(val[components], A[curr]); 32 | for ( int i = 0; i < (int)rev_v[curr].size(); i++ ) { 33 | if ( vis[rev_v[curr][i]] ) continue; 34 | dfs_1(rev_v[curr][i]); 35 | } 36 | } 37 | 38 | void dfs_2(int curr,stack&s) 39 | { 40 | vis[curr] = true; 41 | for ( int i = 0; i < (int)scc_v[curr].size(); i++ ) { 42 | if ( vis[scc_v[curr][i]] ) continue; 43 | dfs_2(scc_v[curr][i],s); 44 | } 45 | s.push(curr); 46 | } 47 | 48 | int solve(int n,vector c, vector> edges){ 49 | v=rev_v=scc_v=vector>(n+1,vector()); 50 | A=val=comp=vector(n+1); 51 | ss=vector>(n+1,set()); 52 | stacks; 53 | vis.assign(n+1,false); 54 | components=0; 55 | int x, y; 56 | for ( int i = 1; i <= n; i++ ) { 57 | A[i]=c[i-1]; 58 | } 59 | 60 | for ( int i = 0; i < edges.size(); i++ ) { 61 | x=edges[i][0],y=edges[i][1]; 62 | v[x].push_back(y); 63 | rev_v[y].push_back(x); 64 | } 65 | 66 | for ( int i = 1; i <= n; i++ ) { 67 | if ( !vis[i] ) dfs_0(i,s); 68 | } 69 | 70 | vis.assign(n+1,false); 71 | 72 | components = 0; 73 | 74 | while ( !s.empty() ) { 75 | int curr = s.top(); 76 | s.pop(); 77 | if ( !vis[curr] ) { 78 | components++; 79 | dfs_1(curr); 80 | } 81 | } 82 | 83 | //Create an scc condensed dag graph 84 | //Number of vertices = components 85 | //Edges -> scc[] 86 | //Value on each node of this scc - val[i] 87 | for ( int i = 0; i < edges.size(); i++ ) { 88 | if ( comp[edges[i][0]] != comp[edges[i][1]] ) { 89 | scc_v[comp[edges[i][0]]].push_back(comp[edges[i][1]]); 90 | } 91 | } 92 | 93 | vis.assign(n+1,false); 94 | //Perform a topological sort on this. 95 | 96 | for ( int i = 1; i <= components; i++ ) { 97 | if ( !vis[i] ) dfs_2(i,s); 98 | } 99 | 100 | int ans = INF; 101 | 102 | while ( !s.empty() ) { 103 | int curr = s.top(); 104 | s.pop(); 105 | ss[curr].insert(val[curr]); 106 | ans = min(ans, val[curr]); 107 | for ( set :: iterator it = ss[curr].begin(); it != ss[curr].end(); it++ ) { 108 | for ( int j = 0; j < (int)scc_v[curr].size(); j++ ) { 109 | ss[scc_v[curr][j]].insert(__gcd(*it, val[scc_v[curr][j]])); 110 | ans = min(ans, __gcd(*it, val[scc_v[curr][j]])); 111 | } 112 | } 113 | } 114 | return ans; 115 | } -------------------------------------------------------------------------------- /55-Subtree Problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void dfs(int x,int p, vector&sub, vector>&v) 5 | { 6 | sub[x]=1; 7 | for(auto itr:v[x]) 8 | { 9 | if(itr!=p) 10 | { 11 | dfs(itr,x,sub,v); 12 | sub[x]+=sub[itr]; 13 | } 14 | } 15 | } 16 | vector subtreeProblem (int n, vector> edges, vector queries) 17 | { 18 | vectorsub(n+1); 19 | vector>v(n+1); 20 | int x,y; 21 | for(int i=0;ians; 28 | dfs(1,-1,sub,v); 29 | for(int i=0;i 2 | using namespace std; 3 | #define fi first 4 | #define se second 5 | 6 | vector>>v; 7 | vectordis; 8 | void dfs(int x ,int p,int w) 9 | { 10 | dis[x]=w; 11 | for(auto itr:v[x]) 12 | { 13 | if(itr.fi!=p) 14 | { 15 | dfs(itr.fi,x,w+itr.se); 16 | } 17 | } 18 | } 19 | vector pathOnTree (int n, int k, vector> edges, vector> queries) 20 | { 21 | dis.resize(n+1); 22 | v=vector>>(n+1,vector>()); 23 | int x,y,val; 24 | for(int i=0;ians; 32 | for(int i=0;i 2 | using namespace std; 3 | 4 | 5 | int ans; 6 | vectorsub; 7 | vector> g; 8 | 9 | void dfs(int k, int par) 10 | { 11 | sub[k]=1; 12 | for(auto it:g[k]) 13 | { 14 | if(it==par) 15 | continue; 16 | dfs(it, k); 17 | sub[k]+=sub[it]; 18 | } 19 | if(sub[k]%2==0&&k!=1) 20 | { 21 | ans++; 22 | } 23 | } 24 | int solve(int n, vector> edges) 25 | { 26 | ans=0; 27 | g=vector>(n+1,vector()); 28 | sub=vector(n+1); 29 | for(int i=0;i 2 | using namespace std; 3 | 4 | int treeDiameter(vector> edges) { 5 | int n=edges.size()+1; 6 | vector>v(n+1); 7 | int x,y; 8 | for(int i=0;iq; 15 | vectorvisit(n+1),dis(n+1,0); 16 | visit[1]=1; 17 | q.push(1); 18 | while(!q.empty()) 19 | { 20 | x=q.front(); 21 | q.pop(); 22 | for(auto itr:v[x]) 23 | { 24 | if(!visit[itr]) 25 | { 26 | q.push(itr); 27 | visit[itr]=1; 28 | dis[itr]=max(dis[itr],dis[x]+1); 29 | } 30 | } 31 | } 32 | int val=0,val1; 33 | for(int i=1;i<=n;i++) 34 | { 35 | if(val 2 | using namespace std; 3 | 4 | vector>adj; 5 | vectorans; 6 | 7 | int bfs(int src,int n) { 8 | int top; 9 | queue q; 10 | vector d(n+1, -1); 11 | d[src] = 0; 12 | ans[src] = max(ans[src], d[src]); 13 | q.push(src); 14 | 15 | while(!q.empty()) { 16 | top = q.front(); 17 | q.pop(); 18 | 19 | for(int v: adj[top]) { 20 | if(d[v] == -1) { 21 | q.push(v); 22 | d[v] = d[top] + 1; 23 | ans[v] = max(ans[v], d[v]); 24 | } 25 | } 26 | } 27 | return top; 28 | } 29 | 30 | 31 | vector treeDistances(int n, vector>edges) 32 | { 33 | ans.assign(n+1,-1); 34 | adj=vector>(n+1,vector()); 35 | int x,y; 36 | vectorvalue; 37 | for(int i=0;i 2 | using namespace std; 3 | #define fi first 4 | #define se second 5 | 6 | vectorsz,label; 7 | int cnt; 8 | int find(int x) 9 | { 10 | if(x!=label[x]) 11 | { 12 | return label[x]=find(label[x]); 13 | } 14 | return x; 15 | } 16 | void Union(int x,int y) 17 | { 18 | int val=find(x),val1=find(y); 19 | if(val==val1) 20 | { 21 | return; 22 | } 23 | if(sz[val]>sz[val1]) 24 | { 25 | swap(val,val1); 26 | } 27 | label[val]=val1; 28 | cnt-=(sz[val1]*(sz[val1]-1))/2; 29 | sz[val1]+=sz[val]; 30 | cnt-=(sz[val]*(sz[val]-1))/2; 31 | cnt+=(sz[val1]*(sz[val1]-1))/2; 32 | } 33 | vector pathQueries(int n, vector> edges, vectorqueries) 34 | { 35 | cnt=0; 36 | int x,y,val; 37 | label.resize(n+1); 38 | sz.assign(n+1,1); 39 | iota(label.begin(),label.end(),0); 40 | vector>>v(n-1); 41 | for(int i=0;i>s; 48 | for(int i=0;ians(queries.size()); 54 | auto itr=s.begin(); 55 | int ptr=0; 56 | while(itr!=s.end()) 57 | { 58 | val=itr->fi; 59 | while(ptrse]=cnt; 67 | itr++; 68 | } 69 | return ans; 70 | } -------------------------------------------------------------------------------- /61-Subtree Queries.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int timer; 5 | vector> adj; 6 | vectorstart,endd,bit; 7 | 8 | void update(int i, int delta, int n) { 9 | for(; i <= n; i += i&-i){ 10 | bit[i] += delta; 11 | } 12 | } 13 | 14 | int query(int i) { 15 | int sum = 0; 16 | for(; i > 0; i -= i&-i) { 17 | sum += bit[i]; 18 | } 19 | return sum; 20 | } 21 | 22 | void dfs(int u, int p,vector&value,int n) { 23 | start[u] = ++timer; 24 | update(timer, value[u-1], n); 25 | 26 | for(int v: adj[u]){ 27 | if(v!=p) { 28 | dfs(v, u,value,n); 29 | } 30 | } 31 | endd[u] = timer; 32 | } 33 | 34 | vector subtreeQuery(int n, vector a, vector>edges, vector> queries) 35 | { 36 | timer=0; 37 | start.assign(n+5,0); 38 | endd.assign(n+5,1e9); 39 | bit.assign(n+5,0); 40 | adj=vector>(n+5,vector()); 41 | int type; 42 | int x,y,val; 43 | for(int i = 0; i ans; 49 | dfs(1, 0, a, n); 50 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>v; 5 | vectortin,tout; 6 | int timer; 7 | void dfs(int x,int p) 8 | { 9 | tin[x]=++timer; 10 | for(auto itr:v[x]) 11 | { 12 | if(itr!=p) 13 | { 14 | dfs(itr,x); 15 | } 16 | } 17 | tout[x]=timer; 18 | } 19 | bool comp(const array&arr1, const array&arr2) 20 | { 21 | return arr1[1] treeQuery(int n, vector a, vector> edges, vector> queries) 24 | { 25 | timer=0; 26 | tin.resize(n+1); 27 | tout.resize(n+1,1e9); 28 | v=vector>(n+1,vector()); 29 | int x,y; 30 | for(int i=0;ians(n); 37 | vector>temp(n+2); 38 | dfs(1,0); 39 | temp[n+1]={0,n+5,n+1}; 40 | for(int i=1;i<=n;i++) 41 | { 42 | temp[i]={0,tin[i],i}; 43 | } 44 | sort(temp.begin(),temp.end(),comp); 45 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>g,go; 5 | vectortin,tout,dep; 6 | int timer; 7 | 8 | void dfs(int node,int par) 9 | { 10 | tin[node] = timer++; 11 | 12 | if(par == -1) dep[node] = 0; 13 | else dep[node] = dep[par] + 1; 14 | 15 | go[dep[node]].push_back(tin[node]); 16 | 17 | for(auto x : g[node]) 18 | if(x != par) dfs(x,node); 19 | 20 | tout[node] = timer - 1; 21 | } 22 | 23 | int cnt(int x,int l,int r) 24 | { 25 | return upper_bound(go[x].begin(),go[x].end(),r) - upper_bound(go[x].begin(),go[x].end(),l-1); 26 | } 27 | 28 | vector countDescendants (int n, vector> edges, vector>queries) 29 | { 30 | timer=0; 31 | g = go = vector>(n+1); 32 | tin = tout = dep =vector(n+1); 33 | int x,y; 34 | for (int i =0; ians; 41 | for(int i=0;i 2 | using namespace std; 3 | 4 | int tim; 5 | vectortin,tout,st,lazy,c,arr; 6 | vector> g; 7 | 8 | void dfs(int k, int par) 9 | { 10 | tin[k]=++tim; 11 | arr[tim]=c[k]; 12 | for(auto &it:g[k]) 13 | if(it!=par) 14 | dfs(it, k); 15 | tout[k]=tim; 16 | } 17 | 18 | void propogate(int node, int L, int R) 19 | { 20 | if(L!=R) 21 | lazy[node*2]=lazy[node*2+1]=lazy[node]; 22 | st[node]=lazy[node]; 23 | lazy[node]=0; 24 | } 25 | 26 | void build(int node, int L, int R) 27 | { 28 | if(L==R) 29 | { 30 | st[node]=arr[L]; 31 | return; 32 | } 33 | int M=(L+R)>>1; 34 | build(node*2, L, M); 35 | build(node*2+1, M+1, R); 36 | st[node]=st[node*2]|st[node*2+1]; 37 | } 38 | 39 | void update(int node, int L, int R, int i, int j, int val) 40 | { 41 | if(lazy[node]) 42 | propogate(node, L, R); 43 | if(jR) 44 | return; 45 | if(i<=L && R<=j) 46 | { 47 | st[node]=val; 48 | if(L!=R) 49 | { 50 | lazy[node*2]=val; 51 | lazy[node*2+1]=val; 52 | } 53 | return; 54 | } 55 | int M=(L+R)>>1; 56 | update(node*2, L, M, i, j, val); 57 | update(node*2+1, M+1, R, i, j, val); 58 | st[node]=st[node*2]|st[node*2+1]; 59 | } 60 | 61 | int query(int node, int L, int R, int i, int j) 62 | { 63 | if(lazy[node]) 64 | propogate(node, L, R); 65 | if(jR) 66 | return 0; 67 | if(i<=L && R<=j) 68 | return st[node]; 69 | int M=(L+R)>>1; 70 | return query(node*2, L, M, i, j)|query(node*2+1, M+1, R, i, j); 71 | } 72 | 73 | vector solve(int n, vector a, vector> edges,vector> queries) 74 | { 75 | tin=tout=c=arr=vector(n+1); 76 | st= lazy=vector((4*n)+1); 77 | g=vector>(n+1,vector()); 78 | tim=0; 79 | for(int i=1;i<=n;i++) 80 | { 81 | c[i]=a[i-1]; 82 | c[i]=(1<ans; 94 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>v,up; 5 | vectortin,tout; 6 | int level,timer; 7 | void dfs(int x,int p) 8 | { 9 | tin[x]=++timer; 10 | up[x][0]=p; 11 | for(int i=1;i<=level;i++) 12 | { 13 | up[x][i]=up[up[x][i-1]][i-1]; 14 | } 15 | for(auto itr:v[x]) 16 | { 17 | if(itr!=p) 18 | { 19 | dfs(itr,x); 20 | } 21 | } 22 | tout[x]=++timer; 23 | } 24 | bool is_ancestor(int u, int v) 25 | { 26 | return tin[u]<=tin[v] && tout[u]>=tout[v]; 27 | } 28 | int lca(int u,int v) 29 | { 30 | if(is_ancestor(u,v)) 31 | { 32 | return u; 33 | } 34 | if(is_ancestor(v,u)) 35 | { 36 | return v; 37 | } 38 | for(int i=level;i>=0;i--) 39 | { 40 | if(!is_ancestor(up[u][i],v)) 41 | { 42 | u=up[u][i]; 43 | } 44 | } 45 | return up[u][0]; 46 | } 47 | 48 | vector LCA(int n, vector>edges, vector>queries) 49 | { 50 | tin.resize(n+1); 51 | tout.resize(n+1,1e9); 52 | level=ceil(log2(n)); 53 | up.assign(n+1,vector(level+1)); 54 | v=vector>(n+1,vector()); 55 | int x,y,val; 56 | vectorans; 57 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>v,up; 5 | vectortin,tout,depth; 6 | int level,timer; 7 | void dfs(int x,int p,int d) 8 | { 9 | tin[x]=++timer; 10 | up[x][0]=p; 11 | depth[x]=d; 12 | for(int i=1;i<=level;i++) 13 | { 14 | up[x][i]=up[up[x][i-1]][i-1]; 15 | } 16 | for(auto itr:v[x]) 17 | { 18 | if(itr!=p) 19 | { 20 | dfs(itr,x,d+1); 21 | } 22 | } 23 | tout[x]=++timer; 24 | } 25 | bool checker(int u,int v) 26 | { 27 | return tin[u]<=tin[v] && tout[u]>=tout[v]; 28 | } 29 | int lca(int u,int v) 30 | { 31 | if(checker(u,v)) 32 | { 33 | return u; 34 | } 35 | if(checker(v,u)) 36 | { 37 | return v; 38 | } 39 | for(int i=level;i>=0;i--) 40 | { 41 | if(!checker(up[u][i],v)) 42 | { 43 | u=up[u][i]; 44 | } 45 | } 46 | return up[u][0]; 47 | } 48 | vector distanceQuery(int n, vector>edges, vector>queries) 49 | { 50 | int x,y,val; 51 | level=ceil(log2(n)); 52 | tin.resize(n+1); 53 | tout.resize(n+1,1e9); 54 | depth.resize(n+1); 55 | v=vector>(n+1,vector()); 56 | up.assign(n+1,vector(level+1)); 57 | for(int i=0;ians; 65 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>v,up; 5 | vectortin,tout,pre; 6 | int level,timer; 7 | void dfs(int x,int p,int w,vector& a) 8 | { 9 | tin[x]=++timer; 10 | up[x][0]=p; 11 | pre[x]=w^pre[p]; 12 | for(int i=1;i<=level;i++) 13 | { 14 | up[x][i]=up[up[x][i-1]][i-1]; 15 | } 16 | for(auto itr:v[x]) 17 | { 18 | if(itr!=p) 19 | { 20 | dfs(itr,x,a[itr-1],a); 21 | } 22 | } 23 | tout[x]=++timer; 24 | } 25 | bool is_ancestor(int u, int v) 26 | { 27 | return tin[u]<=tin[v] && tout[u]>=tout[v]; 28 | } 29 | int lca(int u,int v) 30 | { 31 | if(is_ancestor(u,v)) 32 | { 33 | return u; 34 | } 35 | if(is_ancestor(v,u)) 36 | { 37 | return v; 38 | } 39 | for(int i=level;i>=0;i--) 40 | { 41 | if(!is_ancestor(up[u][i],v)) 42 | { 43 | u=up[u][i]; 44 | } 45 | } 46 | return up[u][0]; 47 | } 48 | vector pathXor(int n, vector a, vector> edges, vector> queries){ 49 | 50 | tin.assign(n+1,-1); 51 | tout.assign(n+1,1e9); 52 | v=vector>(n+1,vector()); 53 | pre.resize(n+1); 54 | level=ceil(log2(n)); 55 | up.assign(n+1,vector(level+1)); 56 | int x,y,val; 57 | for(int i=0;ians; 65 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>v,up,maxi; 5 | vectorin,out,depth; 6 | int level,timer; 7 | void dfs(int x,int p,int d, vector&a) 8 | { 9 | up[x][0]=p; 10 | depth[x]=d; 11 | in[x]=++timer; 12 | if(p!=0) 13 | { 14 | maxi[x][0]=max(a[x-1],a[p-1]); 15 | } 16 | 17 | for(int i=1;i<=level;i++) 18 | { 19 | up[x][i]=up[up[x][i-1]][i-1]; 20 | maxi[x][i]=max(maxi[x][i-1],maxi[up[x][i-1]][i-1]); 21 | } 22 | 23 | for(auto itr:v[x]) 24 | { 25 | if(itr!=p) 26 | { 27 | dfs(itr,x,d+1,a); 28 | } 29 | } 30 | out[x]=++timer; 31 | } 32 | bool is_ancestor(int u,int v) 33 | { 34 | return in[u]<=in[v] && out[u]>=out[v]; 35 | } 36 | int lca(int u,int v) 37 | { 38 | if(is_ancestor(u,v)) 39 | { 40 | return u; 41 | } 42 | if(is_ancestor(v,u)) 43 | { 44 | return v; 45 | } 46 | 47 | for(int i=level;i>=0;i--) 48 | { 49 | if(!is_ancestor(up[u][i],v)) 50 | { 51 | u=up[u][i]; 52 | } 53 | } 54 | return up[u][0]; 55 | } 56 | int solve(int u,int v,int anc, vector&a) 57 | { 58 | int val=a[u-1],val1=a[v-1]; 59 | if(u!=anc) 60 | { 61 | for(int i=level;i>=0;i--) 62 | { 63 | if(depth[up[u][i]]>=depth[anc]) 64 | { 65 | val=max(val,maxi[u][i]); 66 | u=up[u][i]; 67 | } 68 | } 69 | } 70 | if(v!=anc) 71 | { 72 | for(int i=level;i>=0;i--) 73 | { 74 | if(depth[up[v][i]]>=depth[anc]) 75 | { 76 | val1=max(val1,maxi[v][i]); 77 | v=up[v][i]; 78 | } 79 | } 80 | } 81 | return max(val,val1); 82 | } 83 | 84 | vector maximumPath (int n, vector a, vector> edges, vector> queries) 85 | { 86 | v=vector>(n+1,vector()); 87 | in= vector(n+1,0); 88 | out= vector(n+1, 1e9); 89 | timer=0; 90 | level=ceil(log2(n)); 91 | up=vector>(n+1,vector(level+1,0)); 92 | depth=vector(n+1,0); 93 | maxi=vector>(n+1,vector(level+1,0)); 94 | int x,y,val; 95 | for(int i=0;ians; 103 | for(int i=0;i 2 | using namespace std; 3 | #define mod 1000000007 4 | #define fi first 5 | #define se second 6 | #define pb push_back 7 | 8 | vector>>v; 9 | vectorpre; 10 | void dfs(int x,int p,long long w) 11 | { 12 | long long val=w; 13 | if(p!=0) 14 | { 15 | val=val^pre[p]; 16 | } 17 | pre[x]=val; 18 | for(auto itr:v[x]) 19 | { 20 | if(itr.fi!=p) 21 | { 22 | dfs(itr.fi,x,itr.se); 23 | } 24 | } 25 | } 26 | long long xorDistances(int n, vector> edges) 27 | { 28 | pre.assign(n+1,0); 29 | v=vector>>(n+1,vector>()); 30 | 31 | long long x,y,val,val1,ans=0; 32 | for(int i=0;i>suf(n+1,vector(61)); 41 | for(int i=n;i>=1;i--) 42 | { 43 | for(int j=0;j<=60;j++) 44 | { 45 | val1=(long long)1< 2 | using namespace std; 3 | 4 | vector>v; 5 | vectorsz,sub,ans; 6 | void dfs_1(int x,int p) 7 | { 8 | sz[x]=1; 9 | sub[x]=0; 10 | for(auto itr:v[x]) 11 | { 12 | if(itr!=p) 13 | { 14 | dfs_1(itr,x); 15 | sz[x]+=sz[itr]; 16 | sub[x]+=(sub[itr]+sz[itr]); 17 | } 18 | } 19 | } 20 | void dfs(int x,int p,int n) 21 | { 22 | int val=sub[x],par; 23 | if(p!=0) 24 | { 25 | par=ans[p]-sub[x]-sz[x]; 26 | val=par+val+n-sz[x]; 27 | ans[x]=val; 28 | } 29 | for(auto itr:v[x]) 30 | { 31 | if(itr!=p) 32 | { 33 | dfs(itr,x,n); 34 | } 35 | } 36 | } 37 | vector distanceSum(int n, vector> edges) 38 | { 39 | int x,y,val; 40 | v=vector>(n+1,vector()); 41 | sz.assign(n+1,0); 42 | sub.assign(n+1,0); 43 | ans.assign(n+1,0); 44 | for(int i=0;idistance; 54 | for(int i=1;i<=n;i++) 55 | { 56 | distance.push_back(ans[i]); 57 | } 58 | return distance; 59 | } -------------------------------------------------------------------------------- /71-Maximum White Subtree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | vector>adj; 6 | void dfs1(int nd , int pr, vector&dp1, vector&a) 7 | { 8 | dp1[nd] = a[nd-1] == 1 ? 1 : -1; 9 | 10 | for (auto ch : adj[nd]) 11 | { 12 | if (ch == pr) 13 | continue; 14 | 15 | dfs1(ch, nd,dp1,a ); 16 | dp1[nd] += max(0, dp1[ch]); 17 | } 18 | } 19 | 20 | void dfs2(int nd, int pr ,vector &dp2, vector&dp1) 21 | { 22 | dp2[nd] = dp1[nd]; 23 | 24 | if (pr) 25 | { 26 | int val = dp2[pr] - max(0, dp1[nd]); 27 | dp2[nd] += max(0, val); 28 | } 29 | 30 | for (auto ch : adj[nd]) 31 | { 32 | if (ch == pr) 33 | continue; 34 | 35 | dfs2(ch, nd,dp2,dp1); 36 | } 37 | } 38 | 39 | vector maxWhiteSubtree(int n, vector a, vector> edges) 40 | { 41 | adj=vector>(n+1,vector()); 42 | vectordp1(n+1),dp2(n+1); 43 | vectorans; 44 | int x,y; 45 | for (int i = 0; i < n - 1; ++i) 46 | { 47 | x=edges[i][0],y=edges[i][1]; 48 | adj[x].push_back(y); 49 | adj[y].push_back(x); 50 | } 51 | 52 | dfs1(1,0,dp1,a); 53 | dfs2(1,0,dp2,dp1); 54 | 55 | for(int i=1;i<=n;i++) 56 | { 57 | ans.push_back(dp2[i]); 58 | } 59 | return ans; 60 | 61 | } -------------------------------------------------------------------------------- /72-Choosing Capital for Treeland.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | vector>v; 6 | vectorsub,ans; 7 | unordered_map>m; 8 | void dfs_1(int x,int p) 9 | { 10 | sub[x]=0; 11 | for(auto itr:v[x]) 12 | { 13 | if(itr!=p) 14 | { 15 | dfs_1(itr,x); 16 | int cnt=0; 17 | if(m[itr].find(x)!=m[itr].end()) 18 | { 19 | cnt=1; 20 | } 21 | sub[x]+=sub[itr]+cnt; 22 | } 23 | } 24 | } 25 | void dfs(int x,int p) 26 | { 27 | if(p!=0) 28 | { 29 | int par=ans[p]-sub[x]; 30 | if(m[x].find(p)!=m[x].end()) 31 | { 32 | par--; 33 | } 34 | ans[x]=sub[x]+par; 35 | if(m[p].find(x)!=m[p].end()) 36 | { 37 | ans[x]++; 38 | } 39 | } 40 | for(auto itr:v[x]) 41 | { 42 | if(itr!=p) 43 | { 44 | dfs(itr,x); 45 | } 46 | } 47 | } 48 | vector choosingCapital(int n, vector> edges) 49 | { 50 | v=vector>(n+1,vector()); 51 | ans=vector(n+1); 52 | sub=vector(n+1); 53 | m.clear(); 54 | int x,y,val; 55 | for(int i=0;ivec; 66 | val=1e9; 67 | for(int i=1;i<=n;i++) 68 | { 69 | val=min(val,ans[i]); 70 | } 71 | for(int i=1;i<=n;i++) 72 | { 73 | if(val==ans[i]) 74 | { 75 | vec.push_back(i); 76 | } 77 | } 78 | return vec; 79 | } -------------------------------------------------------------------------------- /73-Distance in tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector>v; 5 | vector>sub,ans; 6 | void dfs_1(int x,int p,int k) 7 | { 8 | sub[x][0]=1; 9 | for(auto itr:v[x]) 10 | { 11 | if(itr!=p) 12 | { 13 | dfs_1(itr,x,k); 14 | for(int i=0;i<=k;i++) 15 | { 16 | sub[x][i+1]+=sub[itr][i]; 17 | } 18 | } 19 | } 20 | } 21 | void dfs(int x,int p,int k) 22 | { 23 | if(p!=0) 24 | { 25 | vectorvec(k+5); 26 | ans[x]=sub[x]; 27 | vec=ans[p]; 28 | for(int i=1;i<=k;i++) 29 | { 30 | vec[i]-=sub[x][i-1]; 31 | } 32 | for(int i=0;i<=k;i++) 33 | { 34 | ans[x][i+1]+=vec[i]; 35 | } 36 | } 37 | for(auto itr:v[x]) 38 | { 39 | if(itr!=p) 40 | { 41 | dfs(itr,x,k); 42 | } 43 | } 44 | } 45 | long long distance(int n, int k, vector> edges) 46 | { 47 | v=vector>(n+1,vector()); 48 | sub=vector>(n+1,vector(k+5)); 49 | ans=vector>(n+1,vector(k+5)); 50 | long long x,y,val; 51 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector>v; 5 | vectorsub,dp,ans; 6 | void dfs_1(int x,int p,vector a) 7 | { 8 | sub[x]=a[x-1]; 9 | for(auto itr:v[x]) 10 | { 11 | if(itr!=p) 12 | { 13 | dfs_1(itr,x,a); 14 | sub[x]+=sub[itr]; 15 | dp[x]+=dp[itr]+sub[itr]; 16 | } 17 | } 18 | } 19 | void dfs(int x,int p) 20 | { 21 | long long par; 22 | if(p!=0) 23 | { 24 | par=ans[p]-dp[x]-sub[x]; 25 | ans[x]=par+dp[x]+sub[1]-sub[x]; 26 | } 27 | for(auto itr:v[x]) 28 | { 29 | if(itr!=p) 30 | { 31 | dfs(itr,x); 32 | } 33 | } 34 | } 35 | long long treeMaxCost(int n, vector a ,vector> edges) 36 | { 37 | v=vector>(n+1,vector()); 38 | sub.assign(n+1,0); 39 | ans.assign(n+1,0); 40 | dp.assign(n+1,0); 41 | long long x,y,val; 42 | for(int i=0;i 2 | using namespace std; 3 | 4 | int m,n; 5 | vector> g; 6 | vector> dir={{0,-1},{-1,-1},{1,-1},{0,1},{-1,1},{1,1}}; 7 | int S,T; 8 | int flow; 9 | 10 | void bfs(vector &pre){ 11 | queue q; 12 | q.push(S); 13 | vector visited(m*n+2,0); 14 | visited[S]=1; 15 | while(!q.empty()){ 16 | int cur=q.front(); 17 | q.pop(); 18 | for(int i=0;i pre(m*n+2,-1); 30 | bfs(pre); 31 | if(pre[T]==-1) break; 32 | int v=T; 33 | while(true){ 34 | int u=pre[v]; 35 | g[u][v]--; 36 | g[v][u]++; 37 | v=u; 38 | if(v==S) break; 39 | } 40 | flow++; 41 | } 42 | } 43 | 44 | int maxStudents(vector> seats) { 45 | m=seats.size(); 46 | n=seats[0].size(); 47 | S=m*n; 48 | T=m*n+1; 49 | g=vector>(m*n+2,vector(m*n+2,0)); // residual capacity 50 | int seatcnt=0; 51 | for(int i=0;i=m || nj<0 || nj>=n || seats[ni][nj]=='#') continue; 61 | g[i*n+j][ni*n+nj]=1; 62 | } 63 | }else{ 64 | g[i*n+j][T]=1; 65 | } 66 | } 67 | } 68 | flow=0; 69 | EK(); 70 | return seatcnt-flow; 71 | } 72 | -------------------------------------------------------------------------------- /76-Download Speed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define ll long long 4 | 5 | struct FlowEdge { 6 | int v, u; ll cap, flow = 0; 7 | FlowEdge(int v, int u, ll cap) : v(v), u(u), cap(cap) {} 8 | }; 9 | struct Dinic 10 | { 11 | const ll FLOW_INF = 1e18; 12 | int n, m = 0, s, t; 13 | vector edges; vector> adj; 14 | vector level, ptr; queue q; 15 | Dinic(int n, int s, int t) : n(n), s(s), t(t) { adj.resize(n); level.resize(n); ptr.resize(n); } 16 | void addEdge(int u, int v, ll cap) 17 | { 18 | edges.emplace_back(u, v, cap); edges.emplace_back(v, u, 0); 19 | adj[u].push_back(m); adj[v].push_back(m+1); 20 | m += 2; 21 | } 22 | bool bfs() 23 | { 24 | while (!q.empty()) 25 | { 26 | int v = q.front(); q.pop(); 27 | for (int id : adj[v]) 28 | { 29 | if (edges[id].cap - edges[id].flow < 1) continue; 30 | if (level[edges[id].u] != -1) continue; 31 | level[edges[id].u] = level[v] + 1; 32 | q.push(edges[id].u); 33 | } 34 | } 35 | return level[t] != -1; 36 | } 37 | ll dfs(int v, ll pushed) 38 | { 39 | if (pushed == 0) return 0; 40 | if (v == t) return pushed; 41 | for (int &cid = ptr[v]; cid < (int)adj[v].size(); cid++) 42 | { 43 | int id = adj[v][cid], u = edges[id].u; 44 | if (level[v] + 1 != level[u] || edges[id].cap - edges[id].flow < 1) continue; 45 | ll tr = dfs(u, min(pushed, edges[id].cap - edges[id].flow)); 46 | if (tr == 0) continue; 47 | edges[id].flow += tr; edges[id ^ 1].flow -= tr; 48 | return tr; 49 | } 50 | return 0; 51 | } 52 | ll flow() 53 | { 54 | ll f = 0; 55 | while (true) 56 | { 57 | fill(level.begin(), level.end(), -1); 58 | level[s] = 0; 59 | q.push(s); 60 | if (!bfs()) break; 61 | fill(ptr.begin(), ptr.end(), 0); 62 | while (ll pushed = dfs(s, FLOW_INF)) f += pushed; 63 | } 64 | return f; 65 | } 66 | }; 67 | // O(N^2 * E) 68 | long long solve(int n, vector> edges) 69 | { 70 | Dinic dinic(n+1, 1, n); 71 | for(int i=0;i 2 | using namespace std; 3 | 4 | vector countPairs(int n, vector> edges, vector queries) { 5 | vector cnt(n + 1), sorted_cnt(n + 1), res; 6 | vector> shared(n + 1); 7 | for (auto &e : edges) { 8 | sorted_cnt[e[0]] = cnt[e[0]] = cnt[e[0]] + 1; 9 | sorted_cnt[e[1]] = cnt[e[1]] = cnt[e[1]] + 1; 10 | ++shared[min(e[0], e[1])][max(e[0], e[1])]; 11 | } 12 | sort(begin(sorted_cnt), end(sorted_cnt)); 13 | for (auto &q : queries) { 14 | res.push_back(0); 15 | for (int i = 1, j = n; i < j; ){ 16 | if (q < sorted_cnt[i] + sorted_cnt[j]){ 17 | res.back() += (j--) - i; 18 | } 19 | else{ 20 | ++i; 21 | } 22 | } 23 | for (auto i = 1; i <= n; ++i){ 24 | for (auto [j, sh_cnt]: shared[i]){ 25 | if (q < cnt[i] + cnt[j] && q + sh_cnt >= cnt[i] + cnt[j]){ 26 | --res.back(); 27 | } 28 | } 29 | } 30 | } 31 | return res; 32 | } -------------------------------------------------------------------------------- /78-Longest Increasing Path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int n,m,dx[4]={1,-1,0,0},dy[4]={0,0,-1,1}; 5 | int dfs(int x,int y,vector>&dp,vector>&matrix) 6 | { 7 | if(dp[x][y]!=-1) 8 | { 9 | return dp[x][y]; 10 | } 11 | int val=1; 12 | for(int i=0;i<4;i++) 13 | { 14 | int p=x+dx[i]; 15 | int q=y+dy[i]; 16 | if(p>=0 && q>=0 && p> matrix) { 24 | n=matrix.size(),m=matrix[0].size(); 25 | vector>dp(n+1,vector(m+1,-1)); 26 | int ans=0; 27 | for(int i=0;i 2 | using namespace std; 3 | #define maxn 100005 4 | 5 | vector g[maxn], w[maxn]; 6 | bool u[maxn]; 7 | int cnt[maxn]; 8 | long long res; 9 | 10 | void dfs(int v,int n) 11 | { 12 | u[v] = true; 13 | for (int i = 0; i < g[v].size(); i++) 14 | { 15 | int to = g[v][i]; 16 | if (u[to]) 17 | continue; 18 | dfs(to,n); 19 | res += min(cnt[to], n - cnt[to]) * (long long)2 * w[v][i]; 20 | cnt[v] += cnt[to]; 21 | } 22 | } 23 | long long holi(int n,vector> edges) 24 | { 25 | for (int i = 0; i < n; i++) 26 | { 27 | g[i].clear(); 28 | w[i].clear(); 29 | u[i] = false; 30 | cnt[i] = 1; 31 | } 32 | for (int i = 0; i < n - 1; i++) 33 | { 34 | int x, y, z; 35 | x=edges[i][0],y=edges[i][1],z=edges[i][2]; 36 | --x; 37 | --y; 38 | g[x].push_back(y); 39 | g[y].push_back(x); 40 | w[x].push_back(z); 41 | w[y].push_back(z); 42 | } 43 | res = 0; 44 | dfs(0,n); 45 | return res; 46 | } -------------------------------------------------------------------------------- /80-Distinct Colors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | #define maxn 100005 4 | 5 | vector>v; 6 | vectorsz,ans,col; 7 | void dfs(int x,int p) 8 | { 9 | sz[x]+=1; 10 | for(auto itr:v[x]) 11 | { 12 | if(itr!=p) 13 | { 14 | dfs(itr,x); 15 | sz[x]+=sz[itr]; 16 | } 17 | } 18 | } 19 | mapm; 20 | void solve(int x,int p,bool keep, vector* vec[]) 21 | { 22 | int mx=-1,bigchild=-1; 23 | for(auto itr:v[x]) 24 | { 25 | if(itr!=p && mx(); 46 | } 47 | vec[x]->push_back(x); 48 | m[col[x]]++; 49 | for(auto itr:v[x]) 50 | { 51 | if(itr!=p && itr!=bigchild) 52 | { 53 | for(auto it:*vec[itr]) 54 | { 55 | m[col[it]]++; 56 | vec[x]->push_back(it); 57 | } 58 | } 59 | } 60 | ans[x-1]=m.size(); 61 | if(!keep) 62 | { 63 | for(auto itr:*vec[x]) 64 | { 65 | m[col[itr]]--; 66 | if(m[col[itr]]==0) 67 | { 68 | m.erase(col[itr]); 69 | } 70 | } 71 | } 72 | } 73 | vector solve(int n, vector a, vector> edges) 74 | { 75 | m.clear(); 76 | vector *vec[n+1]; 77 | v=vector>(n+1,vector()); 78 | sz=col=vector(n+1); 79 | ans=vector(n); 80 | for(int i=0;i