Lightoj – 1285 – DRAWING SIMPLE POLYGON

Link :Problem

Solution:
1. Answer is impossible only when all the points are co-linear
2. For finding the order, sort them by their polar angle in respect of pivot( The point with minimum y co-ordinate, tie breaks with minimum x co-ordinate) . If their are more than one point with same polar angle , the points which distance is smaller comes first.
3. As you can see , you can go in the sorted order, there will be no intersection, But the problem is the last polar angle.

Let’s consider the case,

5
0 0
10 0
0 1
0 2
0 3

// This is also their sorted order, As we can see, if we go with the order ,we can not make a closed polygon, To make a closed polygon, Just reverse all the point on the last polar angle

The final order would be
0 0
10 0
0 3
0 2
0 1

My code :





/*
 
 *************************
 Id  : Matrix.code
 Task:
 Date:
 
 **************************
 
 */

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl; #define Di(n) int n;si(n) #define Dii(a,b) int a,b;si(a);si(b) #define Diii(a,b,c) int a,b,c;si(a);si(b);si(c) #define Si(n) si(n) #define Sii(a,b) si(a);si(b) #define Siii(a,b,c) si(a);si(b);si(c) #define min(a,b) ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void io(){freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}

struct PT {
      int  x,y,id;
      PT(){}
      PT(int _x,int _y){x=_x,y=_y;}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y);}
      PT operator * (double c) const { return PT(x*c,y*c);}
      PT operator / (double c) const { return PT(x/c,y/c);}
      void input(){scanf("%d %d",&x,&y);}
};

double dot(PT p,PT q){ return p.x * q.x + p.y * q.y;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
double dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

/*************************** END OF TEMPLATE ****************************/
const int N = 2005;

PT point[N];
PT pivot;
bool cmp(PT a, PT b)
{
      double k = cross(a-pivot,b-pivot);
      if(fabs(k) < EPS) {
            return dist2(a,pivot) < dist2(b,pivot); } else return k > 0;
}
int main()
{
      Di(t);
      int cs = 0;
      while(t--){
            Di(n);
            forn(i,n){
                  point[i].input();
                  point[i].id = i;
            }
            int iM = point[0].y, id = 0;
            for(int i =1; i < n; i ++ ) {
                  if(point[i].y < iM || (point[i].y == iM && point[i].x < point[id].x)) { id = i; iM = point[i].y; } } swap(point[0] , point[id]); pivot = point[0]; sort(point , point + n , cmp ); int line = 0; for( line = n-2; line > 0 ; line -- ) {
                  double nn = cross(point[n-1] -pivot , point[line] - pivot );
                  if(fabs(nn) > EPS) {
                        break;
                  }
            }
            if(line == 0) printf("Case %d:\nImpossible\n", ++cs);
            else {
                  reverse(point + line+ 1, point + n );
                  printf("Case %d:\n", ++cs);
                  forn(i,n) {if(i) printf(" "); printf("%d", point[i].id);}
                  printf("\n");
            }
      }
      return 0;
}


Hill Climbing Algorithm

Discussion:
From Wiki:
In computer science, hill climbing is a mathematical optimization technique which belongs to the family of local search. It is an iterative algorithm that starts with an arbitrary solution to a problem, then attempts to find a better solution by incrementally changing a single element of the solution. If the change produces a better solution, an incremental change is made to the new solution, repeating until no further improvements can be found.

Now this algorithm can be applied to convex functions. It finds a local maximum or minimum. As we know, Ternary Search is applied to find local maximum or minimum .So I will discuss a problem , solve it using Ternary search and
again apply hill climbing algorithm to solve the maxima or minima..

Intended Problem :
Problem Link : Link
Solution :

1. Ternary Search

From the problem we , ternary search on x,y,z, like nested ternary search. Find the best possible answer



#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-8
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}


struct PT {
      double  x,y,z;
      PT(double x=0, double y=0, double z=0) : x(x), y(y) ,z(z){}
      PT(const PT &p) : x(p.x), y(p.y) ,z(p.z)  {}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y , z+ p.z);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y , z - p.z);}
      PT operator * (double c) const { return PT(x*c,y*c,z*c);}
      PT operator / (double c) const { return PT(x/c,y/c,z/c);}
      void input(){scanf("%lf %lf %lf",&x,&y,&z);}
};

double dot(PT p,PT q){ return p.x * q.x + p.y * q.y + p.z * q.z ;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
double dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1001;
int n;
PT point[N];

double calc(double x,double y, double z)
{
      double iM = 0;
      forn(i,n){
            iM = max( iM ,(dist2(point[i] , PT(x,y,z))));
      }
      return iM;
}
pair<double,double>  can1(double x,double y)
{
      double lo = -1e4, hi = 1e4 , mid , ans;
      forn(i,100){
            double f = lo + (hi - lo ) /3;
            double g = lo + 2 * (hi - lo) / 3;
            if(calc(x,y,f) < calc(x,y,g)) {
                  ans = f;
                  hi = g;
            }else { ans = g;lo = f;}
            if(fabs(lo-hi) < EPS) break;
      }
      return mp(calc(x,y,ans) ,ans );
}

typedef pair<double,double> Pair;
pair<double, pair<double,double> >  can(double x)
{
      double lo = -1e4, hi= 1e4 , mid,ans;
      forn(i,100){
            double f = lo + (hi - lo ) /3;
            double g = lo + 2 * (hi - lo) / 3;
            Pair fx = can1(x,f);
            Pair gx = can1(x,g);
            if(fx.Fr < gx.Fr) {
                  hi = g;
                  ans = f;
            }
            else {
                  lo = f;
                  ans = g;
            }
            if(fabs(lo-hi) < EPS) break;
            
      }
      Pair t = can1(x,ans);
      return mp(t.Fr , mp(ans, t.Sc));
}
int main()
{
      Si(n);
      forn(i,n) {
            point[i].input();
      }
      double lox = -1e4 , hix = 1e4 , midx, ansx = 0.0;
      Pair k;
      forn(i,100) {
            double fx = lox + (hix - lox )/ 3;
            double gx = lox + 2 * (hix - lox )/ 3;
            pair<double, pair<double,double> > f1 = can(fx);
            pair<double, pair<double,double> > f2 = can(gx);
            if(f1.Fr < f2.Fr) {
                  ansx = fx;
                  hix = gx;
                  k = f1.Sc;
            }
            else {
                  lox = fx;
                  ansx = gx;
                  k = f2.Sc;
            }
            if(fabs(lox-hix) < EPS) break;
            
      }
      
      printf("%.10lf %.10lf %.10lf\n", ansx ,k.Fr,k.Sc);
      
      return 0;
}


Now Second Solution: Hill climbing algorithm

In hill climbing algorithm, we first assume a answer, then increment this answer to the optimal answer.
We use a gradient which gradually lower down, that is the changing ratio or slope becomes smaller.
I hope after seeing the code, we will all able to understand.


#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}


struct PT {
      double  x,y,z;
      PT(double x=0, double y=0, double z=0) : x(x), y(y) ,z(z){}
      PT(const PT &p) : x(p.x), y(p.y) ,z(p.z)  {}
      PT operator + (const PT &p) const { return PT(x+p.x , y + p.y , z+ p.z);}
      PT operator - (const PT &p) const { return PT(x-p.x , y - p.y , z - p.z);}
      PT operator * (double c) const { return PT(x*c,y*c,z*c);}
      PT operator / (double c) const { return PT(x/c,y/c,z/c);}
      void input(){scanf("%lf %lf %lf",&x,&y,&z);}
};

double dot(PT p,PT q){ return p.x * q.x + p.y * q.y + p.z * q.z ;}
double cross(PT p,PT q) {return p.x*q.y - p.y*q.x;}
double dist2(PT p,PT q) {return dot(p-q , p-q);}
double DIM(PT p) {return sqrt(p.x*p.x+p.y*p.y);}

/*************************** END OF TEMPLATE ****************************/
const int N = 1001;
int n;
PT point[N];

int main()
{
      Si(n);
      forn(i,n) {
            point[i].input();
      }
      double x=0,y=0,z=0;
      double lambda = 1; // This is slope,
      forn(i,100000){
            double d = -1;
            int opt = -1;
            forn(j,n) {
                  double k = (dist2(point[j] , PT(x,y,z)));
                  if( k > d ) {
                        d = k;
                        opt = j;
                  }
            }
           // Adjusting the variables so that we go towards the optimal solution
            x+= lambda*(point[opt].x - x);
            y+= lambda* (point[opt].y - y);
            z+= lambda*(point[opt].z - z);
            lambda*= .999; // Decreasing the slope, This is important,
            
      }
      printf("%.10lf %.10lf %10lf\n", x,y,z);
      
      return 0;
}

UVA – 12616 – Gymman vs Fila

Link : 12616
Aproach: Articulation- Point, dfs Tree

Algo:

1. Find articulation points
2. For each point u , all the ways that makes u as articulation point, keep track and small calculation needed.
See the code below

/*
 
 *************************
 Id  : Matrix.code
 Task:
 Date:
 
 **************************
 
 */

#include <bits/stdc++.h>
using namespace std;

/*------- Constants---- */

#define Long                    long long
#define ull                     unsigned long long
#define mod                     1000000007
#define MEMSET_INF              63
#define MEM_VAL                 1061109567
#define forn(i,n)               for( int i=0 ; i < n ; i++ )
#define mp(i,j)                 make_pair(i,j)
#define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
#define pb(a)                   push_back((a))
#define all(x)                  (x).begin(),(x).end()
#define gc                      getchar_unlocked
#define PI                      acos(-1.0)
#define INF                     1<<29
#define EPS                     1e-9
#define Fr                      first
#define Sc                      second
#define Sz                      size()
#define lc                      ((n)<<1)
#define rc                      ((n)<<1|1)
#define db(x)                   cout << #x << " -> " << x << endl;
#define Di(n)                   int n;si(n)
#define Dii(a,b)                int a,b;si(a);si(b)
#define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
#define Si(n)                   si(n)
#define Sii(a,b)                si(a);si(b)
#define Siii(a,b,c)             si(a);si(b);si(c)
#define min(a,b)                ((a)>(b) ? (b) : (a) )
#define max(a,b)                ((a)>(b) ? (a):(b))
/*---- short Cuts ------- */
#define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
typedef pair<int, int> ii;
typedef vector<int > vi ;
typedef vector<Long> vl;
/*------ template functions ------ */
#ifndef getchar_unlocked
#define getchar_unlocked getchar
#endif
template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
      if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
void io(){freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}

/*************************** END OF TEMPLATE ****************************/
const int N = 2e4+5;
Long tot = 0;
int Time[N] , low[N];
int dfn= 0;
vi G[N];
bool isAp[N];
int SZ=  0;
bool vis[N];
int n,m;
int color[N];

Long dfs(int u,int p )
{
      Time[u] = low[u] = dfn ++;
      vis[u]=1;
      int sub = 0, sb2 = 0 ;
      int cnt = 0;
      Long temp = 0;
      for(auto a: G[u]) {
            if(a==p) continue;
            if(vis[a])low[u] = min(low[u] , Time[a]);
            else {
                  Long ret = dfs(a,u);
                  sub += ret;
                  if(low[a] >= Time[u] ) {
                        isAp[u]=1;
                        temp += sb2 * ret;
                        sb2 += ret;
                  }
                  low[u] = min(low[u] , low[a]);
                  cnt ++;
            }
      }
      if(p==-1) isAp[u] = cnt>1;
      
      if(isAp[u]) {
            temp += sb2 * (SZ - sb2 -1 );
            tot += 2 * temp;
      }
      return sub + 1;
}


Long dfs1(int u,int col)
{
      Long r = 1;
      color[u]  = col;
      for(auto a: G[u]) if(color[a] < 0)  r+= dfs1(a,col);
      return r;
}
int main()
{
      
      Di(t);
      int cs = 0;
      while(t--) {
            Sii(n,m);
            forn(i,m) {
                  Dii(a,b);
                  G[a].pb(b);
                  G[b].pb(a);
            }
            tot = 0;
            dfn = 0;
            ms(isAp,0);
            ms(vis,0);
            ms(color,-1);
            int col= 0;
            for(int i=1;i<=n;i++) {
                  if(color[i] < 0 ) {
                        SZ = dfs1(i,col++);
                        dfs(i,-1);
                        
                  }
            }
            printf("Case %d: %lld\n",++cs, tot  );
            forn(i,n+1) G[i].clear();
            
      }
      return 0;
}

Breadth-first search

Slight modification and translation in English From http://e-maxx.ru/algo/bfs

Breadth-first search ( BFS) :

breadth-first search – is one of the basic algorithms on graphs.
The result of the algorithm is the shortest path length in unweighted graph, ie, the path that contains the smallest number of edges.
The algorithm works O (n + m) for, where n- the number of vertices m- number of edges.

Description of the algorithm :

The input to the algorithm is a graph (unweighted), and a starting vertex S . A graph can be either directed or undirected, algorithm works for all.

The algorithm can be understood as a process of “ignition” of the graph: at the zero step only the tip (The starting vertex) S ignite. At each step on each burning vertex, fire has spread to of all its neighbors; ie in one iteration of the algorithm is an expansion of “Ring of Fire” in width per unit (hence the name of the algorithm).

We create a queue q to store the burning vertices and a boolean array used[] to determine the state of each vertex. If used[v] is false,Then v is not burned or burning and vise-versa.

Initially placed in a queue is just the S tip, and, as for all the other vertices. Then, an algorithm is a cycle: as long as the queue is not empty. The front of the queue is taken, pop from the queue and check all its neighbour if there are any which is not set into fire. If there are some vertices that is not visited( not set into fire) , mark them visited and push them in queue.

As a result, when the queue is empty, all vertices that reachable from S , with each will reach to the shortest path. It is also possible to calculate the length of the shortest paths (which just need to have an array of path d[]). To restore the shortest path, We maintain a array P[] ,which denotes the immediate parents vertex from which the vertex is visited. Using a loop, we can climb up to the starting vertex and find the actual shortest path.

Coding :

Normally An array of vector is widely used in graph problems. So I am going to follow this convention

const int N = 1000;     // N is Maximum number of vertices
vector G[N];	// The graph
int n;			// number of vertices
int s;			// Starting vertex


Main Part :

queue q;
q.push (s);
vector used (n);
vector d (n), p (n);
used[s] = true;
p[s] = -1;
while (!q.empty()) {
	int v = q.front();
	q.pop();
	for (int i=0; i<G[v].size(); i ++ ) {
		int to = g[v][i];
		if (!used[to]) {
			used[to] = true;
			q.push (to);
			d[to] = d[v] + 1;
			p[to] = v;
		}
	}
}

To restore the original path. For S–> T , we climb up to the starting vertex

if(!used[T]) printf("NO PATH\n"); // Not reachable
else {
	vector path;
	for(int v= T; v != s; v= p[v]) {
		path.push_back(v);
	}
	reverse(path.begin(), path.end());
	for(int i=0;i<path.size(); i++ ) {
		printf("%d ", path[i]);
	}
}

Application of the algorithm:
1. Shortest Path in unweighted graph.
2. Search for connected components in the graph O (n + m) .

To do so, for each vertex
1. check if it is visited or not. If visited , end
2. If not visited , then new Component is found, run bfs from this vertex

Pseduo-code

for a in vertex
if(used[a]== 0 ) {
component ++;
bfs(a);
}

Problem : Links

3. Finding a solution to any problem (the game) with the least number of moves, if each state of the system can be represented by a vertex of the graph, and the transitions from one state to another – edges of the graph.

A classic example – a game where the robot moves on the field, when he can move the boxes located on the same field, and the need for a minimum number of moves required to move the boxes into position. We solve it detour across the graph, where the state (top) is a set of coordinates: the coordinates of the robot, and the coordinates of all the boxes

4. Finding the shortest cycle in a directed unweighted graph: searches in width of each node; as soon as the process we are trying to bypass the current peaks on some edge in the already visited the top, it means that we have found the shortest cycle and stop the tour in width; found among all such cycles (one from each run bypass) choose the shortest.

5. Find all the edges, lying on any shortest path between a given pair of (a, b)vertices. To do this, start the search in from Starting vertex a and end vertex b . We denote d_a []the array shortest distances obtained from the first bypass and through d_b []- in a second bypass. Now, for every edge (u, v) is easy to check whether it is on any fast track: the criterion is the d_a [u] + 1 + d_b [v] = d_a [b] condition.
6. Find all the vertices on any shortest path between a given pair of (a, b)vertices. To do this, start the search in 2 widths: a from, to and b from. We denote d_a []the array shortest distances obtained from the first bypass and through d_b []- in a second bypass. Now, for each vertex vis easy to check whether it is on any fast track: the criterion is the d_a [v] + d_b [v] = d_a [b]condition.

Problems will be included later.

TPCPPLAR – Popular SPOJ

Problem Link: Link
Problem Statement:

Given a directed graph G , N vertices and M arcs.
A node X called “acessible” to Y if there is a path from X to Y
A node X called “popular” if every node Y in V fulfill one of two conditions :
1. X is acessible to Y
2. Y is acessible to X
The Problem : Given graph G, count the number of popular node.

Discussion:

First , The given graph can form cycle, So we calculate SCC, and construct a new graph connecting the SCC.
In the new graph , we do following

  • Topological sort
  • Later in the text comparison A < B means that vertex A stands before vertex B in topological order.
    Now let's notice that for vertex V an edge that connects vertices V1  V doesn’t influence on the fact whether V is popular. Let’s remove all such edges and see whether there exists a vertex V1  V that has zero input degree, if so — V is not popular, otherwise it is.
  • When Processing the vertex as topsort, We keep two things, the number of vertex in the right that has zero incoming edge and the number of vertex in the left that has zero outgoing edge. When processing a vertex , we add the incoming edge to the vertex and after the process, we delete all the outgoing edge of the vertex.
  • /*
     
     *************************
     Id  : Matrix.code
     Task: TPCPPLAR - Popular
     Date: 23 OCT-2015
     
     **************************
     
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
    template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
    template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
    void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}
    
    /*************************** END OF TEMPLATE ****************************/
    const int N = 150005;
    vi G[N],R[N], D[N] , top, C[N] , nodes[N] , RD[N];
    bool vis[N];
    int color[N];
    int in[N],out[N];
    int Pos[N] , a1[N] , a2[N] ;
    
    void dfs1(int u)
    {
          vis[u]=1;
          for(auto a: G[u]){
                if(vis[a] == 0 ) dfs1(a);
          }
          top.pb(u);
    }
    void dfs2(int u,int col)
    {
          nodes[col].pb(u);
          color[u] = col;
          for(auto a: R[u]) {
                if(color[a] < 0 ) dfs2(a,col);
          }
    }
    
    void dfs3(int u)
    {
          vis[u]=1;
          for(auto a: D[u]){
                if(vis[a] == 0 ) dfs3(a);
          }
          top.pb(u);
    }
    
    
    
    int main()
    {
          Dii(n,m);
          forn(i,m){
                Dii(u,v);
                G[u].pb(v);
                R[v].pb(u);
          }
          ms(vis,0);
          top.clear();
          for(int i=1;i<=n;i++) {
                if(vis[i] == 0 ) {
                      dfs1(i);
                }
          }
          reverse(all(top));
          ms(color,-1);
          int col = 0;
          for(auto a : top ) {
                if(color[a] < 0 ) {
                      dfs2(a,col++);
                }
          }
    
          // Construction of new graph
          for(int i=1;i<=n;i++) {
                for(auto p : G[i] ){
                      if(color[i] != color[p]) {
                            D[color[i]].pb(color[p]);
                            RD[color[p]].pb(color[i]);
                            in[color[p]] ++;
                            out[color[i]] ++;
                      }
                }
          }
          // All the edge need to be unique, otherwise we can update indegree and outdegree for the same edge
          for(int i=0;i<col;i++) {
                sort(all(D[i]));
                D[i].resize(unique(all(D[i])) - D[i].begin());
                sort(all(RD[i]));
                RD[i].resize(unique(all(RD[i])) - RD[i].begin());
          }
    
          // Top-sort
          ms(vis,0);
          top.clear();
          for(int i=0;i < col; i ++ ) {
                if(vis[i] == 0 ) {
                      dfs3(i);
                }
          }
          reverse(all(top));
          int Lz= 0, Rz = 0; // The two value to keep
          for(int i = 0;i< col; i ++ ) if(in[i] == 0 ) Rz++;
          vi Ans;
          for(auto i: top ) {
                if(in[i]==0) Rz--;
                for(auto a: RD[i]) {
                      if(out[a] == 0 ) Lz--;
                      out[a] ++;
                }
                if(Lz || Rz ) {
                      
                }
                else {
                      for(auto a: nodes[ i]) Ans.pb(a);
                }
                for(auto a: D[i]) {
                      in[a] --;
                      if(in[a] == 0 ) Rz++;
                      out[i] --;
                }
                if(out[i] ==0 ) Lz ++;
          }
          cout<< Ans.Sz<<endl;
          sort(all(Ans));
          for(auto a : Ans) printf("%d " , a) ;
          
          
          return 0;
    }
    
    

    Uva – 10740 – Not the Best

    Problem Link : Problem

    Discussion:
    This problem is a variant of Dijkastra’s algorithm.
    Notice that k<=10,
    For any k th shortest path, one node can be update at most k times,So in typical dijkastra's algorithm ,we were keeping a boolean array to note a vertex is finished updating.

    Here is typical dijkastra code:

    struct Node{
    	int v,w;
    	bool operator <(const Node & a) const {
    		return w > a.w;
    	}
    };
    
    vector<pair<int,int> > G[MAXN];
    
    int dij(int s,int dest)
    {
    	memset(d,63,sizeof(d));
    	memset(vis,0,sizeof(vis));
    	
    	d[s]=0;
    	priority_queue<Node> pq;
    	pq.push(Node(0,s));
    
    	while(!pq.empty()){
    		Node p= pq.top();pq.pop(); // Extract the minimum
    		if(vis[p.v]) continue;		// Here we check if is update is finished or not
    		vis[p.v] = 1;				// Mark it as finished , Now relax the edge
    		d[p.v] = p.w;
    		for(int i= 0;i < G[p.v].size(); i ++ ) {
    			int v = G[p.v][i].first;
    			int c = G[p.v][i].second;
    			pq.push(Node(c+d[p.v] , v ));
    		}
    	}
    	return d[dest];
    }
    
    
    

    This code can be modified so that it allows at most k times update for a node
    this is done using a int array in place of vis.

    Solution Code:

    
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x)
    {
        register int c = gc();
        x = 0;
        int neg = 0;
        for(; ((c<48 | c>57) && c != '-'); c = gc());
        if(c=='-') {
            neg=1;
            c=gc();
        }
        for(; c>47 && c<58; c = gc()) {
            x = (x<<1) + (x<<3) + c - 48;
        }
        if(neg) x=-x;
    }
    template <class T> inline T bigmod(T p,T e,T M)
    {
        Long ret = 1;
        for(; e > 0; e >>= 1) {
            if(e & 1) ret = (ret * p) % M;
            p = (p * p) % M;
        }
        return (T)ret;
    }
    template <class T> inline T gcd(T a,T b)
    {
        if(b==0)return a;
        return gcd(b,a%b);
    }
    template <class T> inline T modinverse(T a,T M)
    {
        return bigmod(a,M-2,M);
    }
    void IN()
    {
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    }
    
    /*************************** END OF TEMPLATE ****************************/
    const int N = 105;
    int n,m,s,dis,k;
    
    int d[11][N];
    int vis[N];
    
    vector<pair<int,int> > G[N];
    struct Node{
    	int Fr,Sc;
    	bool operator<(const Node & a) const {
    		return Fr > a.Fr;
    	}
    };
    void SSP(int s)
    {
    
        for(int i=1; i<=n; i++ ) forn(j,k+1) d[j][i] = INF;
        ms(vis,0);
    
        priority_queue<Node> pq;
        pq.push({0,s});
        d[0][s]= 0;
        while(!pq.empty()) {
            Node f = pq.top();
            pq.pop();
            if(vis[f.Sc] > k ) continue;
    
            d[vis[f.Sc]][f.Sc] = f.Fr;
            vis[f.Sc] ++;
            int u = f.Sc;
            for(int i= 0; i < G[u].Sz; i++) {
                int v= G[u][i].Fr;
                int c = G[u][i].Sc;
                pq.push({f.Fr+c, v});
    
            }
        }
        if(d[k-1][dis]==INF) printf("-1\n");
        else {
            // for(int i=0;i<k;i++) printf("%d %d\n", i, d[i][dis]);
            printf("%d\n", d[k-1][dis]);
        }
    
    }
    int main()
    {
        //IN();
        while(scanf("%d%d",&n,&m)==2) {
            if(n==0&&m==0) break;
            Siii(s,dis,k);
            forn(i,m) {
                Diii(u,v,w);
                G[u].pb(mp(v,w));
    
            }
            SSP(s);
            for(int i=1;i<=n;i++) G[i].clear();
        }
    
        return 0;
    }
    
    

    Further Try : LOJ

    Uva – 702 – The Vindictive Coach

    Discussion:
    N <= 22
    The first method popped in mind, would bitmask dp but N =22 is to high for bitmasking.
    Observation:

    Let’s think, We insert The first element in the array,M .
    This number partition the remaining numbers into two parts
    A-> The numbers less than M
    B -> The number greater than M
    After choosing the first element, We need to choose smaller number than M , so we can take any one element to be the inserted element.and with this insertion we go to the next state where we need to choose from the higher elements,Note That, which number is in the list does’t matter only the size of the partition and the move which we need to take.

    Let a,b is the current partition size, move is the current move that need to take
    The recurrence relation as follows
    Long calc(int a,int b,int move)
    {
    	
    	if(a==0 && b==0) return 1;
    	if(a<=0 && move == down ) return 0;
    	if(b<=0 && move == up ) 	return 0;
    	
    	if(dp[a][b][move] !=-1 ) return dp[a][b][move];
    	Long ret = 0;
    	if(move == down ){
    		for(int i=1;i<=a;i++){
    			ret += calc(a-i,b+i-1, up);
    		}
    	}
    	else {
    		for(int i=1;i<=b;i++){
    			ret += calc(a+i-1,b-i,down);
    		}
    	}
    	return dp[a][b][move] = ret;
    }
    
    


    Special Case :
    ** if n =3 , choose 3 then follow the same recurtion

    Under this consideration the problem is solved using dp in O(n^3)

    /*
     
     *************************
     Id  : Matrix.code
     Task:
     Date:
     
     **************************
     
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define Long                    long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<1|1)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<Long> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}
    template <class T> inline T bigmod(T p,T e,T M){Long ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
    template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
    template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
    void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}
    
    /*************************** END OF TEMPLATE ****************************/
    const int N = 24;
    enum{
    	down=0,up=1
    };
    Long dp[N][N][2];
    
    Long calc(int a,int b,int move)
    {
    	
    	if(a==0 && b==0) return 1;
    	if(a<=0 && move == down ) return 0;
    	if(b<=0 && move == up ) 	return 0;
    	
    	if(dp[a][b][move] !=-1 ) return dp[a][b][move];
    	Long ret = 0;
    	if(move == down ){
    		for(int i=1;i<=a;i++){
    			ret += calc(a-i,b+i-1, up);
    		}
    	}
    	else {
    		for(int i=1;i<=b;i++){
    			ret += calc(a+i-1,b-i,down);
    		}
    	}
    	return dp[a][b][move] = ret;
    }
    
    int main()
    {
    	//IN();
    	int n,m;
    
    	while(scanf("%d %d",&n,&m)==2){
    		
    		if(n<=2) {
    			printf("1\n");
    			continue;
    		}
    		if(m==1){
    			ms(dp,-1);
    			Long iM = calc(1,n-3,down);
    			cout<<iM<<endl;
    			
    		}else {
    			ms(dp,-1);
    			Long iM = calc(m-1,n-m,down);
    			cout <<max(1,iM) << endl;
    		}
    	}
    	return 0;
    }
    
    

    Bitonic Travelling SalesMan Problem

    Discussion :
    From CP3

    Given a list of coordinates of n vertices on 2D Euclidean space that are already sorted by x-coordinates (and
    if tie, by y-coordinates), find a tour that starts from the leftmost vertex, then goes strictly
    from left to right, and then upon reaching the rightmost vertex, the tour goes strictly from
    right to left back to the starting vertex. This tour behavior is called ‘bitonic’

    Although a Bitonic TSP tour of a set of n vertices is usually longer than the standard
    TSP tour, this bitonic constraint allows us to compute a ‘good enough tour’ in O(n 2 ) time
    using Dynamic Programming—as shown below—compared with the O(2^n × n^2 ) time for the
    standard TSP tour

    The main observation needed to derive the DP solution is the fact that we can (and have
    to) split the tour into two paths: Left-to-Right (LR) and Right-to-Left (RL) paths. Both
    paths include vertex 0 (the leftmost vertex) and vertex n-1 (the rightmost vertex). The LR
    path starts from vertex 0 and ends at vertex n-1. The RL path starts from vertex n-1 and
    ends at vertex 0.
    Remember that all vertices have been sorted by x-coordinates (and if tie, by y-coordinates).
    We can then consider the vertices one by one. Both LR and RL paths start from vertex
    0. Let v be the next vertex to be considered. For each vertex v ∈ [1 . . . n − 2], we decide
    whether to add vertex v as the next point of the LR path (to extend the LR path further to
    the right) or as the previous point the returning RL path (the RL path now starts at v and
    goes back to vertex 0). For this, we need to keep track of two more parameters: p1 and p2.
    Let p1/p2 be the current ending/starting vertex of the LR/RL path, respectively.
    The base case is when vertex v = n − 1 where we just need to connect the two LR and
    RL paths with vertex n − 1.

    double dp1(int v, int p1, int p2) {
    if (v == n-1)  return d[p1][v] + d[v][p2];
    if (memo3d[v][p1][p2] > -0.5)  return memo3d[v][p1][p2];
    return memo3d[v][p1][p2] = min(
          d[p1][v] + dp1(v+1, v, p2),
          d[v][p2] + dp1(v+1, p1, v));
    }
    

    However, the time complexity of dp1 with three parameters: (v, p1, p2) is O(n 3 ). This is
    not efficient, as parameter v can be dropped and recovered from 1+max(p1, p2) . The improved DP solution is shown below and runs in O(n 2 ).

    So complete Solution:

    /*
     
     *************************
     Id  : Matrix.code
     Task:
     Date:
     
     **************************
     
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define LL                      long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<11)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define Si(n)                   si(n)
    #define Sii(a,b)                si(a);si(b)
    #define Siii(a,b,c)             si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    typedef vector<LL> vl;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
    template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
    template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
    void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}
    
    /*************************** END OF TEMPLATE ****************************/
    const int N = 105;
    int n;
    double dp[N][N];
    int p[N][2];
    double d[N][N];
    bool vis[N][N];
    double calc(int p1,int p2)
    {
    	int v= max(p1,p2)+1;
    	if(v==n-1){
    		return d[p1][v] + d[p2][v];
    	}
    	if(vis[p1][p2]) return dp[p1][p2];
    	double r= INF;
    	dp[p1][p2] = min( d[p1][v] + calc(v,p2) , d[p2][v] + calc(p1,v));
    	vis[p1][p2] = 1;
    	return dp[p1][p2];
    }
    
    int main()
    {
    
    	while(scanf("%d",&n)==1) {
    		for(int i=0;i<n;i++) {
    			Sii(p[i][0],p[i][1]);
    		}
    		forn(i,n)forn(j,n){
    			d[i][j] = sqrt((p[i][0]- p[j][0]) * (p[i][0] - p[j][0]) + (p[i][1]-p[j][1])*(p[i][1]-p[j][1]));
    		}
    		ms(vis,0);
    		printf("%.2lf\n", calc(0,0));
    	}
    	return 0;
    }
    

    Furthur solving:
    islands

    LOJ – 1018 – Brush (IV)

    Link : Problem
    Approach: Bitmask DP

    It is a easy bitmask problem unless strict time limit. Choose any two points from the given set, and then calculate the points that are covered by the line joining them. This lead to 2^n * (n^3) solution. This surely time limits.

    Optimization 1:
    We don’t need to calculate the points covered by each line twice. What we can do, Prepocess them and stored them in a mask.
    This lead us to 2^n * (n^2) solution.

    Solution Code:

    /*
     
     *************************
     Id  : Matrix.code
     Task: 1018 - Brush (IV)
     Date: 10/9/15.
     **************************
     
     */
     
    #include <bits/stdc++.h>
    using namespace std;
     
    /*------- Constants---- */
     
    #define LL                      long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<11)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
    template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
    template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
    void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}
     
    /*************************** END OF TEMPLATE ****************************/
    const int N = 16;
    int n;
    int x[N] , y[N];
    int col[N][N];
     
    int dp[1<<N];
    int p2[1<<N];
    int calc(int mask)
    {
          if(mask==0)return 0;
          if(dp[mask]!=-1) return dp[mask];
          int t = mask;
          vi c;
          while(t){
                int k = t&-t;
                c.pb(p2[k]);
                t-=k;
          }
          int ret= INF;
          if(c.Sz==1) return dp[mask] = 1;
          for(int i=0;i< c.Sz;i ++) {
                for(int j= i+1; j < c.Sz; j ++){
                      int t = col[c[i]][c[j]];
                      ret = min(ret, 1 + calc( mask & col[c[i]][c[j]]));
                }
          }
          return dp[mask]= ret;
    }
    int main()
    {
          for(int i=0;i<16;i++)p2[1<<i] = i;
          Di(t);
          int cs = 0;
          while(t--){
                si(n);
                for(int i=0;i<n;i++){
                      si(x[i]);
                      si(y[i]);
                }
                for(int i=0;i<n;i++){
                      for(int j=i+1; j< n;j++) {
                            col[i][j] = (1<<n)-1;
                            for(int k=0;k<n;k++){
                                  if((x[i]-x[j]) * (y[i]-y[k]) == (y[i]-y[j]) *(x[i] - x[k])) col[i][j] = col[i][j] & (~(1<<k));
                            }
                            col[j][i] = col[i][j];
                      }
                }
                ms(dp,-1);
                int iM = calc((1<<n) -1);
                printf("Case %d: %d\n",++cs ,iM );
                ms(col,0);
          }
          return 0;
         
    }
    

    This is a good solution. But gets TLE.

    Optimization 2 : Let {1,2,3} is the set of points now in consideration, So The number of moves to delete the entire set, We should always a pivot, and another is a rotating one,
    We don’t need to try all possible ways, But fixing any one as pivot, and then try for the best pair .. This optimization leads to 2^n*n solution this get AC 🙂

    
    
    /*
     
     *************************
     Id  : Matrix.code
     Task: 1018 - Brush (IV)
     Date: 10/9/15.
     **************************
     
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define LL                      long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<11)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
    template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
    template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
    void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}
    
    /*************************** END OF TEMPLATE ****************************/
    const int N = 16;
    int n;
    int x[N] , y[N];
    int col[N][N];
    
    int dp[1<<N];
    int p2[1<<N];
    int calc(int mask)
    {
          if(mask==0)return 0;
          if(dp[mask]!=-1) return dp[mask];
          int t = mask;
          vi c;
          while(t){
                int k = t&-t;
                c.pb(p2[k]);
                t-=k;
          }
          int ret= INF;
          if(c.Sz==1) return dp[mask] = 1;
          int pivot = c[0];
          for(int i=1;i< c.Sz;i ++) {
                      ret = min(ret, 1 + calc( mask & col[pivot][c[i]]));
                
          }
          return dp[mask]= ret;
    }
    int main()
    {
          for(int i=0;i<16;i++)p2[1<<i] = i;
          Di(t);
          int cs = 0;
          while(t--){
                si(n);
                for(int i=0;i<n;i++){
                      si(x[i]);
                      si(y[i]);
                }
                for(int i=0;i<n;i++){
                      for(int j=i+1; j< n;j++) {
                            col[i][j] = (1<<n)-1;
                            for(int k=0;k<n;k++){
                                  if((x[i]-x[j]) * (y[i]-y[k]) == (y[i]-y[j]) *(x[i] - x[k])) col[i][j] = col[i][j] & (~(1<<k));
                            }
                            col[j][i] = col[i][j];
                      }
                }
                ms(dp,-1);
                int iM = calc((1<<n) -1);
                printf("Case %d: %d\n",++cs ,iM );
                ms(col,0);
          }
          return 0;
          
    }
    
    
    

    LOJ – 1013 – Love Calculator

    Link : Problem
    Algo : DP

    Let dp[i][j] -> The length of the shortest string that contains a[1…i] and b[1….j] as sub-sequence
    Let dp2[i][j] -> Total number of unique shortest strings which contain a[1…i] and b[1….j] as sub-sequence

    The recurrence relation :

    
    
    if(a[i] == b[j] ) {
          dp[i][j] = 1 + dp[i-1][j-1]; // Just add a[i] to the dp[i-1][j-1]
          dp2[i][j] = dp2[i-1][j-1];
    }
    else {
          dp[i][j] = 1 + min(dp[i][j-1] , dp[i-1][j]); // Check which one is minimum
          if(dp[i][j-1] == dp[i-1][j]) dp2[i][j] = dp2[i][j-1]  + dp2[i-1][j];
          else dp2[i][j] = dp[i][j-1] < dp[i-1][j] ? dp2[i][j-1] : dp2[i-1][j];
    }
    
    

    Solution :

    
    
    
    /*
     
     *************************
     Id  : Matrix.code
     Task: 1013 - Love Calculator
     Date: 10/9/15.
     **************************
     
     */
    
    #include <bits/stdc++.h>
    using namespace std;
    
    /*------- Constants---- */
    
    #define LL                      long long
    #define ull                     unsigned long long
    #define mod                     1000000007
    #define MEMSET_INF              63
    #define MEM_VAL                 1061109567
    #define forn(i,n)               for( int i=0 ; i < n ; i++ )
    #define mp(i,j)                 make_pair(i,j)
    #define lop(i,a,b)              for( int i = (a) ; i < (b) ; i++)
    #define pb(a)                   push_back((a))
    #define all(x)                  (x).begin(),(x).end()
    #define gc                      getchar_unlocked
    #define PI                      acos(-1.0)
    #define INF                     1<<29
    #define EPS                     1e-9
    #define Fr                      first
    #define Sc                      second
    #define Sz                      size()
    #define lc                      ((n)<<1)
    #define rc                      ((n)<<11)
    #define db(x)                   cout << #x << " -> " << x << endl;
    #define Di(n)                   int n;si(n)
    #define Dii(a,b)                int a,b;si(a);si(b)
    #define Diii(a,b,c)             int a,b,c;si(a);si(b);si(c)
    #define min(a,b)                ((a)>(b) ? (b) : (a) )
    #define max(a,b)                ((a)>(b) ? (a):(b))
    /*---- short Cuts ------- */
    #define ms(ara_name,value) memset(ara_name,value,sizeof(ara_name))
    typedef pair<int, int> ii;
    typedef vector<int > vi ;
    /*------ template functions ------ */
    #ifndef getchar_unlocked
    #define getchar_unlocked getchar
    #endif
    template<class T> inline void si(T &x){register int c = gc();x = 0;int neg = 0;for(;((c<48 | c>57) && c != '-');c = gc());
          if(c=='-') {neg=1;c=gc();}for(;c>47 && c<58;c = gc()) {x = (x<<1) + (x<<3) + c - 48;}if(neg) x=-x;}template <class T> inline T bigmod(T p,T e,T M){LL ret = 1;for(; e > 0; e >>= 1){if(e & 1) ret = (ret * p) % M;p = (p * p) % M;} return (T)ret;}
    template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
    template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
    void IN(){    freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);}
    
    /*************************** END OF TEMPLATE ****************************/
    const int N = 35;
    char a[N], b[N];
    LL dp[N][N];
    LL dp2[N][N];
    
    int main()
    {
          
          Di(t);
          int cs = 0;
          while(t--){
                scanf("%s %s", a+1,b+1);
                for(int i=0;i<N;i++) dp[0][i]= dp[i][0] = i,  dp2[i][0] = dp2[0][i] = 1;
                int N1, N2;
                for(int i=1;a[i]; i++ ) N1 = i;
                for(int i=1;b[i]; i++ ) N2 = i;
                for(int i=1; a[i] ; i ++) {
                      for(int j= 1; b[j] ; j ++ ) {
                            if(a[i] == b[j] ) {
                                  dp[i][j] = 1 + dp[i-1][j-1];
                                  dp2[i][j] = dp2[i-1][j-1];
                            }
                            else {
                                  dp[i][j] = 1 + min(dp[i][j-1] , dp[i-1][j]);
                                  if(dp[i][j-1] == dp[i-1][j]) dp2[i][j] = dp2[i][j-1] + dp2[i-1][j];
                                  else dp2[i][j] = dp[i][j-1] < dp[i-1][j] ? dp2[i][j-1] : dp2[i-1][j];
                            }
                            //printf("%d %d %d\n", i,j,dp[i][j]);
                      }
                }
                printf("Case %d: %lld %lld\n",++cs, dp[N1][N2] , dp2[N1][N2]);
          }
          return 0;
          
    }