saurabh's blog

By saurabh13 months ago, In English,

I have been trying this problem http://www.spoj.pl/problems/FPOLICE/. My idea is to modify the single source shortest path problem to 2-D.So instead of using an array to denote the shortest distance I am using a 2-D matrix where state[i][j] indicates the shortest path from the source to the ith node with still having j time left.(The upper limit on left time is denoted by t) Finally I check the last row (state[n-1][j] for all j=t to j=0 ) the minimum cost.If the minimum cost comes out to be INFINITY then there is no way to reach the destination with atleast 0 time remaining.If minimum costs occur for several values of j i pick up the j which is larger.That is the case which yields more remaining time ( i.e. minimum time).For the single source shortest path I started with dijikistra but then switched to bellman-ford for simplicity.(Doesn't looks like o(n^2*t) will be problem)

UPD: Code modified to fix some bugs

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<cstdlib>
#include<stack>
#include<queue>
#include<string>
#include<cstring>


#define PR(x) printf(#x"=%d\n",x)
#define READ2(x,y) scanf("%d %d",&x,&y)
#define REP(i,a) for(int i=0;i<a;i++)
#define READ(x) scanf("%d",&x)
#define PRARR(x,n) for(int i=0;i<n;i++)printf(#x"[%d]=\t%d\n",i,x[i])
const int INF=2<<29;

int costMatr[101][101];
int timeMatr[101][101];
using namespace std;

int main()
	{
	int n;
	int t;
	/*Input section */
	int tstcase;
	scanf("%d",&tstcase);
	while(tstcase--){
	scanf("%d %d",&n,&t);
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			{
			scanf("%d",&timeMatr[i][j]);
			}
	for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
			{
			scanf("%d",&costMatr[i][j]);
			}
	
	
	/*End input */	
	
	int state[101][251]; //state[i][j] represents cost from source node to ith node with j time remaining
	for(int i=1;i<n;i++) 
		for(int j=0;j<=t;j++)
		{
		
		 state[i][j]=INF; //initialize all states to infinity
		
		 }
		 
	for(int i=0;i<=t;i++) state[0][i]=0; //cost to reach 0th node will be 0 regardless of time left
	for(int i=1;i<n;i++)
	if(t-timeMatr[0][i]>=0) state[i][t-timeMatr[0][i]]=costMatr[0][i]; //initialize state matrix for neighbours of source nodeh

	/*DP begin */
	for(int k=t;k>=0;k--)
	
		{
		for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		{
		if(i==j) continue;
		 
			if(costMatr[i][j]+state[i][k]<=state[j][k])
				{
				
				if(k-timeMatr[i][j]>=0) {
				#ifndef ONLINE_JUDGE
				printf("Distance to %dth node updated for time %d. previous value at this state=%d",j,k,state[j][k]);
				#endif
				state[j][k-timeMatr[i][j]]=costMatr[i][j]+state[i][k];
				#ifndef ONLINE_JUDGE
				printf("New value for this time %d =%d\n",k-timeMatr[i][j],state[j][k]);
				#endif
				}
				}
		
			
		}
	}
	
	/*DP END*/
	/*possible answer in state[n-1][t] where t is all possible values of remaining time */
	
	int minCost=INF;
	int minTime=t;	
	for(int k=t;k>=0;k--)
	{
	if(state[n-1][k]<minCost)
	{
	minCost=state[n-1][k];
	minTime=k;
	}
	}
	if(minCost==INF)
	puts("-1");
	else
	printf("%d %d\n",minCost,t-minTime);
	}
	}

Kindly suggest some test cases where my algorithm might be failing.I am almost sure my idea of 2-D Dp is correct,just that I am not able to implement it properly.

UPD: Got the bug.TYpo in if(costMatr[i][j]+state[i][k]<=state[j][k]) should have been if(costMatr[i][j]+state[i][k]<=state[j][k-timeMatr[i][j]])

 
 
 
 
  • Vote: I like it  
  • +2
  • Vote: I do not like it  

 
»
13 months ago, # |
Rev. 2   Vote: I like it +1 Vote: I do not like it

Here is a simple case where the result is 3 3, but your code produces result 9 1:

1
4 5
0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 1
0 9 1 9
9 0 9 1
9 1 0 9
9 9 9 9
  •  
    »
    »
    13 months ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    I had noticed that and fixed that too..Since no one was responding forgot to update the code.Now my code gives correct o/p for your test case.