Sei sulla pagina 1di 18

ICPC HANDBOOK gareebCoders

INDEX
NUMBER THEORY

1. MODULAR EXPONENTIATION 2. FAST I/O


int power ( int m , int n , int mod ) inline int input()
{ {
int temp = m ; char c = getchar() ;
int ans = 1 ; while (c < '0' || c > '9' )
while (n > 0) c = getchar() ;
{ int ret = 0 ;
if ( n%2 == 0 ) while ( c >= '0' && c <= '9' )
{ {
temp = ( temp * temp ) % mod ; ret = 10 * ret + c 48 ;
n /= 2 ; c = getchar() ;
} }
else return ret ;
{ }
ans = ( ans * temp ) %mod ;
n --= 1 ;
}
}
return ans ;
}

3. GCD 4. PRIME FACTORIZATION - SEIVE

int gcd (int a, int b) int minPrime[n + 1];


{
if(!b) for (int i = 2; i * i <= n; ++i) {
return a; if (minPrime[i] == 0) {
return gcd(b, a%b); //if i is prime
return true; for (int j = i * i; j <= n; j += i) {
} if (minPrime[j] == 0) {
minPrime[j] = i;
}
5. EXTENDED EUCLID ALGORITHM }
}
int d , x , y; }
void extendedGCD (int A, int B)
{ for (int i = 2; i <= n; ++i) {
if(B == 0) if (minPrime[i] == 0) {
{ minPrime[i] = i;
d = A; }
x = 1; }
y = 0;
} vector<int> factorize(int n) {
else vector<int> res;
{ while (n != 1) {
extendedGCD (B, A%B); res.push_back(minPrime[n]);
int temp = x; n /= minPrime[n];
x = y; }
y = temp - (A/B)*y; return res;
} }
}
6. BITWISE OPERATIONS 7. FERMATS LITTLE THEOREM
if x & ( x 1 ) = 0 then number is power of 2 If p is a prime number and a is a positive
number less than p then
( x | 1 << n ) returns the number x with nth bit set
a^(p-1) = 1(mod p)
x ^ ( 1 << n ) toggles the state of the nth bit in the a^b mod p = a^(b%(p-1)) mod p
number x

SEGMENT TREE
//Build the segment tree //Range Query

void buildtree(int node, int start, int end) int query(int node, int start, int end, int qstart, int qend)
{ {
if(start>end) if(lazy[node]!=0)
return; marklazy(node,start,end);
if(start==end) if(qstart>end || qend<start || start>end )
{ return 1;
//leaf node logic if(start>=qstart && end<=qend)
return; return tree[node].mx;
} int mid = (start+end)/2;
int mid = (start+end)/2; int p = query(2*node,start,mid,qstart,qend);
buildtree(node*2, start, mid); int q = query(2*node+1,mid+1,end,qstart,qend);
buildtree(node*2+1, mid+1, end); //query logic
//merging logic return max(p,q);
merge(tree[node*2],tree[node*2+1],tree[node]); }

//update segment tree

void update(int node, int start, int end, int qstart, int qend)
{
if(lazy[node]!=0) int mid = (start+end)/2;
marklazy(node,start,end); update(2*node,start,mid,qstart,qend);
if(qstart>end || qend<start || start>end ) update(2*node+1,mid+1,end,qstart,qend);
return; merge(tree[node*2],tree[node*2+1],tree[node]);
if(start>=qstart && end<=qend) }
{
tree[node].point += 1;
if(tree[node].point<tree[node].sz)
{
tree[node].mx = tree[node].facts[tree[node].point];
}
else
tree[node].mx = 1;
if(start!=end)
{
lazy[2*node] += 1;
lazy[2*node+1] += 1;
}
return;
}
DISTINCT SUBSTRING WITH SUFFIX ARRAY

#include <bits/stdc++.h> void suffix_array(string s)


using namespace std; {
#define MX 100000 int l = s.length();
int rnk[20][MX]; int i,j;
int arr[MX],cum[MX],lcpar[MX]; for(i=0;i<l;i++)
rnk[0][i] = s[i]-'a';

struct tuple int cnt,step;


{ tuple t[l+10];
int ind, l, r;
}; for(cnt=1, step=1; cnt < l; cnt=cnt*2, step++)
{
bool comp(tuple a, tuple b) for(i=0;i<l;i++)
{ {
if(a.l==b.l) t[i].ind = i;
{ t[i].l = rnk[step-1][i];
return (a.r<b.r); t[i].r = (i+cnt<l)?rnk[step-1][i+cnt]:-1;
} }
return a.l<b.l; //sort(t,t+l,comp);
} counting_sort(t , l);
for(i=0;i<l;i++)
void counting_sort(tuple t[] , int n) {
{ rnk[step][t[i].ind] = (i>0 && t[i].l==t[i-1].l
int count[MX+9]; && t[i].r==t[i-1].r)?rnk[step][t[i-1].ind]:i;
tuple temp[n + 9]; }
memset(count , 0 , sizeof count); }
for(i=0;i<l;i++)
for(int i = 0 ;i < n ; i++) arr[rnk[step-1][i]] = i;
count[t[i].r + 1]++; }

for(int i = 1 ; i < MX ; i++) int lcp(int i,int j,int n)


count[i] += count[i-1]; {
int res = 0;
for(int i = 0 ; i<n ; i++) if(i==j)
{ return (n-i);
temp[count[t[i].r +1] - 1] = t[i];
count[t[i].r + 1]--; int p= ceil(log(n)/log(2));
}
for(int step = p ; step>=0 && i < n && j < n ; step--)
memset(count , 0 , sizeof count); {
if(rnk[step][i] == rnk[step][j])
for(int i = 0 ; i < n ; i ++) {
count[t[i].l + 1] ++; res += 1<<step;
i += 1<<step;
for(int i = 1 ; i<MX ; i++) j += 1<<step;
count[i] += count[i-1]; }
}
for(int i = n- 1; i>=0 ; i--) return res;
{ }
t[count[temp[i].l + 1] - 1] = temp[i];
count[temp[i].l + 1]--;
}
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false);
string s;
cin>>s;
int q;
cin>>q;

int l=s.length();
int i,j;

suffix_array(s);

cum[0]=l-arr[0];
lcpar[0]=0;

for(i=1;i<l;i++)
lcpar[i]=lcp(arr[i],arr[i-1],l);

for(i=1;i<l;i++)
cum[i] = cum[i-1]+ (l-arr[i]-lcpar[i]);
while(q--)
{
int k;
cin>>k;

int pos = lower_bound(cum,cum+l,k)-cum;

for(i=arr[pos],j=0; j<k-cum[pos-1]+lcpar[pos]; i++,j++)


{
cout<<s[i];
}

cout<<endl;
}
return 0;
}

MOS ALGO FOR DISTINCT ELEMENT IN RANGE

O( (N+M) * sqrt N )

Input Output
5 3
11213 2
3 3
15
24
35
#include <cstdio> int main() {
#include <algorithm> int n;
using namespace std; scanf("%d", &n);
for(int i=0; i<n; i++)
#define N 311111 scanf("%d", &a[i]);
#define A 1111111
#define BLOCK 555 // ~sqrt(N) int m;
scanf("%d", &m);
int cnt[A], a[N], ans[N], answer = 0; for(int i=0; i<m; i++) {
scanf("%d%d", &q[i].L, &q[i].R);
struct node { q[i].L--; q[i].R--;
int L, R, i; q[i].i = i;
}q[N]; }

bool cmp(node x, node y) { sort(q, q + m, cmp);


if(x.L/BLOCK != y.L/BLOCK) {
// different blocks, so sort by block. int currentL = 0, currentR = 0;
return x.L/BLOCK < y.L/BLOCK; for(int i=0; i<m; i++) {
} int L = q[i].L, R = q[i].R;
// same block, so sort by R value while(currentL < L) {
return x.R < y.R; remove(currentL);
} currentL++;
}
void add(int position) { while(currentL > L) {
cnt[a[position]]++; add(currentL-1);
if(cnt[a[position]] == 1) { currentL--;
answer++; }
} while(currentR <= R) {
} add(currentR);
currentR++;
void remove(int position) { }
cnt[a[position]]--; while(currentR > R+1) {
if(cnt[a[position]] == 0) { remove(currentR-1);
answer--; currentR--;
} }
} ans[q[i].i] = answer;
}

for(int i=0; i<m; i++)


printf("%d\n", ans[i]);
}
SEARCH AND INSERT IN TRIE

/* C implementation of search and insert operations // Returns new trie node (initialized to NULLs)
on Trie struct TrieNode *getNode(void)
Output : {
struct TrieNode *pNode = NULL;
the --- Present in trie
these --- Not present in trie pNode = (struct TrieNode *)malloc(sizeof(struct
their --- Present in trie TrieNode));
thaw --- Not present in trie
*/ if (pNode)
#include <stdio.h> {
#include <stdlib.h> int i;
#include <string.h>
#include <stdbool.h> pNode->isLeaf = false;

#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0]) for (i = 0; i < ALPHABET_SIZE; i++)


pNode->children[i] = NULL;
// Alphabet size (# of symbols) }
#define ALPHABET_SIZE (26)
return pNode;
// Converts key current character into index }
// use only 'a' through 'z' and lower case
#define CHAR_TO_INDEX(c) ((int)c - (int)'a') // If not present, inserts key into trie
// If the key is prefix of trie node, just marks leaf node
// trie node void insert(struct TrieNode *root, const char *key)
struct TrieNode {
{ int level;
struct TrieNode *children[ALPHABET_SIZE]; int length = strlen(key);
int index;
// isLeaf is true if the node represents
// end of a word struct TrieNode *pCrawl = root;
bool isLeaf;
}; for (level = 0; level < length; level++)
{
// Returns new trie node (initialized to NULLs) index = CHAR_TO_INDEX(key[level]);
struct TrieNode *getNode(void) if (!pCrawl->children[index])
{ pCrawl->children[index] = getNode();
struct TrieNode *pNode = NULL;
pCrawl = pCrawl->children[index];
pNode = (struct TrieNode *)malloc(sizeof(struct }
TrieNode));
// mark last node as leaf
if (pNode) pCrawl->isLeaf = true;
{ }
int i;

pNode->isLeaf = false;

for (i = 0; i < ALPHABET_SIZE; i++)


pNode->children[i] = NULL;
}

return pNode;
}
// Returns true if key presents in trie, else false // Driver
bool search(struct TrieNode *root, const char *key) int main()
{ {
int level; // Input keys (use only 'a' through 'z' and lower case)
int length = strlen(key); char keys[][8] = {"the", "a", "there", "answer", "any",
int index; "by", "bye", "their"};
struct TrieNode *pCrawl = root;
char output[][32] = {"Not present in trie", "Present in trie"};
for (level = 0; level < length; level++)
{
index = CHAR_TO_INDEX(key[level]); struct TrieNode *root = getNode();

if (!pCrawl->children[index]) // Construct trie


return false; int i;
for (i = 0; i < ARRAY_SIZE(keys); i++)
pCrawl = pCrawl->children[index]; insert(root, keys[i]);
}
// Search for different keys
return (pCrawl != NULL && pCrawl->isLeaf); printf("%s --- %s\n", "the", output[search(root, "the")] );
} printf("%s --- %s\n", "these", output[search(root, "these")] );
printf("%s --- %s\n", "their", output[search(root, "their")] );
printf("%s --- %s\n", "thaw", output[search(root, "thaw")] );

return 0;
}

NCR TERM M-ARY TO 10-ARY 10-ARY TO M-ARY

s=1; string num="0123456789ABCDE"; /*10-ary to m-ary*/


for ( i=1 ; i<=r ; i++ ) char
{ int mToTen(string n, int m) a[16]={0,1,2,3,4,5,6,7,8,9,
s=s*(n-(ri))/i; { A,B,C,D,E,F};
} int multi=1;
return s ; int result=0; string tenToM(int n, int m)
for (int i=n.size()-1;i>=0;i--) {
{ int temp=n;
result+=num.find(n[i])*multi; string result="";
multi*=m; while (temp!=0)
} {
return result; result=a[temp%m]+result;
} temp/=m;
}
return result;
}
SEGMENTED SIEVE

ll segsieve(ll m,ll n)
{
ll b[n-m+10],q,x,i,j;

for(i=0;i<=n-m;i++)
b[i]=1;

if(m==1)
b[0]=0;

q=sqrt(n);

for(i=2;i<=q;i++)
{
x=(m/i);
x*=i;
if(i>=x)
x=i*2;
for(j=x;j<=n;j+=i)
{
if(j>=m)
b[j-m]=0;
}
}

for(i=m;i<=n;i++)
if(b[i-m])
printf("%lld\n",i);
printf("\n");

DIJKSTRAS ALGORITHM ( ELOGV )

Vertex Distance from Source


0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14
#include<bits/stdc++.h> / Prints shortest paths from src to all other vertices
using namespace std; void Graph::shortestPath(int src)
# define INF 0x3f3f3f3f {
// Create a priority queue to store vertices that
// iPair ==> Integer Pair // are being preprocessed. This is weird syntax in C++.
typedef pair<int, int> iPair; // Refer below link for details of this syntax
// http://geeksquiz.com/implement-min-heap-using-stl/
// This class represents a directed graph using priority_queue< iPair, vector <iPair> , greater<iPair> > pq;
// adjacency list representation
class Graph // Create a vector for distances and initialize all
{ // distances as infinite (INF)
int V; // No. of vertices vector<int> dist(V, INF);

// In a weighted graph, we need to store vertex // Insert source itself in priority queue and initialize
// and weight pair for every edge // its distance as 0.
list< pair<int, int> > *adj; pq.push(make_pair(0, src));
dist[src] = 0;
public:
Graph(int V); // Constructor /* Looping till priority queue becomes empty (or all
distances are not finalized) */
// function to add an edge to graph while (!pq.empty())
void addEdge(int u, int v, int w); {
// The first vertex in pair is the minimum distance
// prints shortest path from s // vertex, extract it from priority queue.
void shortestPath(int s); // vertex label is stored in second of pair (it
}; // has to be done this way to keep the vertices
// sorted distance (distance must be first item
// Allocates memory for adjacency list // in pair)
Graph::Graph(int V) int u = pq.top().second;
{ pq.pop();
this->V = V;
adj = new list<iPair> [V]; // 'i' is used to get all adjacent vertices of a vertex
} list< pair<int, int> >::iterator i;
for (i = adj[u].begin(); i != adj[u].end(); ++i)
void Graph::addEdge(int u, int v, int w) {
{ // Get vertex label and weight of current adjacent
adj[u].push_back(make_pair(v, w)); // of u.
adj[v].push_back(make_pair(u, w)); int v = (*i).first;
} int weight = (*i).second;

// If there is shorted path to v through u.


if (dist[v] > dist[u] + weight)
{
// Updating distance of v
dist[v] = dist[u] + weight;
pq.push(make_pair(dist[v], v));
}
}
}

// Print shortest distances stored in dist[]


printf("Vertex Distance from Source\n");
for (int i = 0; i < V; ++i)
printf("%d \t\t %d\n", i, dist[i]);
}
// Driver program to test methods of graph class
int main() 4/47. Fast input:
{
// create the graph given in above fugure inline int input()
int V = 9; {
Graph g(V); char c = getchar() ;
while (c < '0' || c > '9' ) c = getchar() ;
// making above shown graph int ret = 0 ;
g.addEdge(0, 1, 4); while ( c >= '0' && c <= '9' )
g.addEdge(0, 7, 8); {
g.addEdge(1, 2, 8); ret = 10 * ret + c 48 ;
g.addEdge(1, 7, 11); c = getchar() ;
g.addEdge(2, 3, 7); }
g.addEdge(2, 8, 2); return ret ;
g.addEdge(2, 5, 4); }
g.addEdge(3, 4, 9); 7/47. Bellman-Ford Algorithm:
g.addEdge(3, 5, 14);
g.addEdge(4, 5, 10); for ( i = 1 ; i < V ; i++ )
g.addEdge(5, 6, 2); {
g.addEdge(6, 7, 1); for ( j = 0 ; j < E ; j++ )
g.addEdge(6, 8, 6); {
g.addEdge(7, 8, 7); int u = edge[j].src ;
int v = edge[j].dest ;
g.shortestPath(0); int weight = edge[j].weight ;
if ( dist[u] != INT_MAX && dist[u] + weight < dist[v] )
return 0; dist[v] = dist[u] + weight ;
} }
}
11/47. Union by Rank and Path Compression:
12/47. Bitwise operations:

int find ( struct subset subsets [ ] , int i ) -> if x & ( x 1 ) = 0 then number is power of 2
{ -> ( x | 1 << n ) returns the number x with nth bit set
if ( subsets [ i ].parent != i ) -> x ^ ( 1 << n ) toggles the state of the nth bit in the
subsets [ i ].parent = find ( subsets , subsets[i].parent ) ; number x
return subsets[i].parent ;
}
void Union ( struct subset subsets [ ] , int x , int y ) Euler tour:
{ -> for undirected graph:
int xroot = find ( subsets , x ) ; all vertices having non-zero degree must be
int yroot = find ( subsets , y ) ; connected.
if ( subsets [ xroot ].rank < subsets [ yroot ].rank) Eulerian path- 0 or 2 vertices can have odd degree.
subsets [ xroot ].parent = yroot ; Eulerian cycle- all vertices must have even degree.
else if ( subsets [ xroot ].rank > subsets [ yroot ].rank ) -> for directed graph
subsets [ yroot ].parent = xroot ; //these conditions are only for finding existence of
else Eulerian cycle
{ *all vertices having non-zero degree belong to a
subsets [ yroot ].parent = xroot ; single strongly connected components.
subsets [ xroot ].rank++ ; *indegree and outdegree for every vertex must be
} same.
}
15/47. Subsets of a subset generation: KMP Implementation

x=n ; //n is representing the subset void KMPSearch(char *pat, char *txt)
while ( 1 ) {
{ int M = strlen(pat);
int N = strlen(txt);
cout << x ;
int *lps = (int *)malloc(sizeof(int)*M);
if ( x == 0 ) int j = 0; // index for pat[]
break ; int i = 0; // index for txt[]
x = ( x -1 ) & n ; while (i < N)
} {
16/47. Biconnected graph: if (pat[j] == txt[i])
{
graph is biconnected if: j++;
->graph is connected. i++;
->there is no articulation point in the graph. }
if (j == M)
Matrix chain multiplication: {
printf("Found pattern at index %d \n", i-j);
j = lps[j-1];
// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n }
int MatrixChainOrder(int p[], int n) else if (i < N && pat[j] != txt[i])
{ {
int i, j, k, L, q; if (j != 0)
/* m[i,j] = Minimum no. of scalar multiplications j = lps[j-1];
needed to compute the matrix A[i]A[i+1]...A[j] = else
i = i+1;
A[i..j] */ }
for (i = 1; i < n; i++) }
m[i][i] = 0; }
// L is chain length. void computeLPSArray(char *pat, int M, int *lps)
for (L=2; L<n; L++) {
{ int len = 0; // lenght of the previous longest prefix
suffix
for (i=1; i<=n-L; i++) int i=1;
{ lps[0] = 0;
j = i+L-1; while (i < M)
m[i][j] = INT_MAX; {
for (k=i; k<=j-1; k++) if (pat[len] == pat[i])
{ {
len++;
// q = cost/scalar multiplications lps[i] = len;
q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]; i++;
if (q < m[i][j]) }
m[i][j] = q; else if(len != 0)
} {
len=lps[len-1];
}
}
} else
return m[1][n-1]; {
} lps[i] = 0;
i++;
}
}
}
Kruskal

} void KruskalMST(struct Graph* graph)


{
int V = graph->V;
6. Graph struct Edge result[V];
class Graph int e = 0, i = 0;
qsort(graph->edge, graph->E,
{
sizeof(graph->edge[0]), myComp);
int V;
struct subset *subsets =
list<int> *adj; (struct subset*) malloc ( V * sizeof(struct subset) );
void DFSUtil
(int v, bool visited[]); for (int v = 0; v < V; ++v)

bool isCyclicUtil {
(int v, bool visited[], bool *rs);
subsets[v].parent = v;
void TopologicalSortUtil
(int v, bool visited[], stack<int> &Stack); subsets[v].rank = 0;
public:
}
Graph(int V);
void addEdge(int v, int w); while (e < V - 1)
void BFS(int s);
{
void DFS();
bool isCyclic(); struct Edge next_edge = graph->edge[i++];
void TopologicalSort(); int x = find(subsets, next_edge.src);
};
Graph::Graph(int V) int y = find(subsets, next_edge.dest);

{ if (x != y)
this->V = V;
{
adj = new list<int>[V];
} result[e++] = next_edge;
void Graph::addEdge(int v, int w)
Union(subsets, x, y);
{
adj[v].push_back(w); }
}
}
void Graph::BFS(int s)
{ printf("edges in MST\n");
bool *visited = new bool[V]; for (i = 0; i < e; ++i)
for(int i=0;i<V;i++)
visited[i]=false; printf("%d -- %d == %d\n",

list<int> queue; result[i].src,


visited[s] = true; result[i].dest,result[i].weight);
queue.push_back(s);
return;
list<int>::iterator i;
}
Prim
while(!queue.empty())
void PrimMST(struct Graph* graph)
{
s = queue.front(); {
cout << s << " ";
int V = graph->V;
queue.pop_front();
for(i=adj[s].begin(); i!=adj[s].end();++i) int parent[V];
{
int key[V];
if(!visited[*i])
{
visited[*i]=true; struct MinHeap* minHeap
queue.push_back(*i);
} = createMinHeap(V);

} for (int v = 1; v < V; ++v)


}
{
}
void Graph::DFSUtil(int v, bool visited[]) parent[v] = -1;
{
key[v] = INT_MAX;
visited[v]=true;
cout << v << " "; minHeap->array[v]
list<int>::iterator i;
= newMinHeapNode(v, key[v]);
for(i=adj[v].begin();i!=adj[v].end();i++)
if(visited[*i]==false) minHeap->pos[v] = v;
DFSUtil(*i, visited); }
}
key[0] = 0;
void Graph::DFS()
{ minHeap->array[0] = newMinHeapNode(0, key[0]);
bool *visited = new bool[V];
minHeap->pos[0] = 0;
int i;
for(i=0;i<V;i++) minHeap->size = V;
visited[i]=false;
while (!isEmpty(minHeap))
for(i=0;i<V;i++)
if(visited[i]==false) {
DFSUtil(i, visited);
struct MinHeapNode* minHeapNode
}
bool Graph::isCyclicUtil = extractMin(minHeap);
(int v, bool visited[], bool *recStack) int u = minHeapNode->v;
{
if(visited[v] == false) struct AdjListNode* pCrawl

{ = graph->array[u].head;
visited[v] = true;
while (pCrawl != NULL)
recStack[v] = true;
list<int>::iterator i; {
for(i = adj[v].begin(); i != adj[v].end(); ++i)
int v = pCrawl->dest;
{
if (visited[*i]==false if (isInMinHeap(minHeap, v)
&& isCyclicUtil(*i, visited, recStack) )
&& pCrawl->weight < key[v])
return true;
else if (recStack[*i]) {
return true; key[v] = pCrawl->weight;
}
parent[v] = u;

} decreaseKey(minHeap, v, key[v]);
recStack[v] = false;
}
return false;
} pCrawl = pCrawl->next;
bool Graph::isCyclic()
}
{
bool *visited = new bool[V]; }
bool *recStack = new bool[V]; printArr(parent, V);
for(int i = 0; i < V; i++)
{ }
visited[i] = false; Bellman Ford
recStack[i] = false; for ( i = 1 ; i < V ; i++ )
} {
for(int i = 0; i < V; i++) for ( j = 0 ; j < E ; j++ )
if (isCyclicUtil(i, visited, recStack)) {
return true; int u = edge[j].src ;
return false; int v = edge[j].dest ;
} int weight = edge[j].weight ;
void Graph::TopologicalSortUtil if ( dist[u] != INT_MAX
(int v, bool visited[], stack<int> &Stack) && dist[u] + weight < dist[v] )
{ dist[v] = dist[u] + weight ;
visited[v]=true; }
list<int>::iterator i; }
for(i=adj[v].begin();i!=adj[v].end();i++)
if(visited[*i]==false)
TopologicalSortUtil(*i, visited, Stack);
Stack.push(v);
}
Floyd Warshall
void Graph::TopologicalSort()
void floydWarshell (int graph[][V])
{
{
stack<int> Stack;
int dist[V][V], i, j, k;
bool *visited = new bool[V];
for (i = 0; i < V; i++)
int i;
for (j = 0; j < V; j++)
for(i=0;i<V;i++)
dist[i][j] = graph[i][j];
visited[i]=false;
for (k = 0; k < V; k++)
for(i=0;i<V;i++)
{
if(visited[i]==false)
for (i = 0; i < V; i++)
TopologicalSortUtil(i, visited, Stack);
{
while(!Stack.empty())
for (j = 0; j < V; j++)
{
{
cout << Stack.top() << " ";
if (dist[i][k] + dist[k][j] < dist[i][j])
Stack.pop();
dist[i][j] = dist[i][k] + dist[k][j];
}
}
}
}
Union Find
}
class UF
printSolution(dist);
{
}
private:
Connected Components
int *id;
class CC
public:
{
UF(int n)
private:
{
bool *marked;
id=new int[n];
int *id;
for(int i=0;i<n;i++)
int cou=0;
id[i]=i;
void dfs(graph G, int v)
}
{
int root(int i)
marked[v]=true;
{
id[v]=cou;
while(i!=id[i])
for(int &w : G.con(v))
{
{
id[i]=id[id[i]];
if(!marked[w])
i=id[i];
dfs(G,w);
}
}
return i;
}
}
bool iscon(int p, int q)
public:
{
CC(graph G)
return (root(p)==root(q));
{
}
marked = new bool[G.v()];
void join(lli p, lli q)
id = new int[G.v()];
// join the two components (root to root)
for(int v=0;v<G.v();v++)
{
marked[v]=false;
id[root(p)]=id[root(q)];
for(int v=0;v<G.v();v++)
}
{
};
if(!marked[v])
Dijkstra (V^2)
{
int minDistance(int dist[], bool sptSet[])
dfs(G,v);
{
cou++;
int min = INT_MAX, min_index;
}
for (int v = 0; v < V; v++)
}
if (sptSet[v] == false && dist[v] <= min)
}
min = dist[v], min_index = v;
int total()
return min_index;
{
}
return cou;
}
void dijkstra ( int graph[V][V] , int src )
int cid(int v)
{
{
int dist[V] ;
return id[v];
bool sptSet[V] ;
}
for ( int i = 0 ; i < V ; i++ ) {
bool connected(int v,int w)
dist[i] = INT_MAX;
{
sptSet[i] = false ;
return id[v]==id[w];
}
}
dist[src] = 0 ;
};

for ( int count = 0 ; count < V-1 ; count++ )


{
int u = minDistance (dist , sptSet ) ;
sptSet[u] = true ;
for (int v = 0; v < V; v++)
if ( ! sptSet[v] && graph[u][v] && dist[u] != INT_MAX && dist[u]+graph[u][v] <
dist[v] )
dist[v] = dist[u] + graph[u][v] ;
}
}
Djikstra(ElogV)
typedef pair<LL,LL> PII;
int main()
{
long long N , s ;
cin >> N >> s ;
vector < vector < PII > > graph ( N ) ;
for ( int i = 0 ; i < N ; i++ )
{
long long M ;
cin >> M ;
for ( int j =0 ; j < M ; j++ )
{
long long vertex , dist;
cin >> vertex >> dist ;
graph[i].push_back ( make_pair ( dist,vertex ) ) ;
}
}
priority_queue < PII , vector<PII> , greater<PII> > Q;
vector < long long > dist ( N , INF ) , dad ( N , -1 ) ;
Q.push ( make_pair ( 0 , s ) ) ;
dist [ s ] = 0 ;
while ( ! Q.empty () )
{
PII p = Q.top() ;
Q.pop() ;
long long here = p.second ;
for (auto it = graph[here].begin() ; it ! = graph[here].end() ; it++)
{
if ( dist [ here ] + it -> first < dist [ it -> second ] )
{
dist [ it -> second ] = dist [ here ] + it -> first ;
dad [ it -> second ] = here ;
Q.push ( make_pair ( dist [ it -> second ],it -> second)) ;
}
}
}
return 0;
}

Potrebbero piacerti anche