## 10917 - Walk Through the Forest

Moderator: Board moderators

TISARKER
Learning poster
Posts: 88
Joined: Tue Oct 12, 2004 6:45 pm
Contact:

### 10917 - Walk Through the Forest

I have collected Input for this problem from website.
But I can not check it.Because I have used long type array.
Which is not suported by my visual c++ compiler.
I am waiting.
Mr. Arithmetic logic Unit

TISARKER
Learning poster
Posts: 88
Joined: Tue Oct 12, 2004 6:45 pm
Contact:
Will I use dynamic variable?.
If not, Clarify me through example how to use adjacency list.
When M=500000(Five lucks)then what will be hapen.
Because the limit of value of M was not declared.
My another question is : "Can I use long array in uva judge?"
Mr. Arithmetic logic Unit

wook
Learning poster
Posts: 76
Joined: Fri Oct 01, 2004 11:34 am
Location: Korea, Republic Of
method for representation of graph with adjancey list is well-known and easy fomular:

you can find them in many books, or internet pages.

TISARKER wrote:My another question is : "Can I use long array in uva judge?"
Sure, memory is enough.

and I didn't knew that there exist a compiler which doesn't support 1000 * 1000 32-bit-integer marix. BTW, In this problem, i guess that the most of input graphs are sparse graph, so I recommend you to use adjency lists/array rather than matrix.
Sorry For My Poor English.. TISARKER
Learning poster
Posts: 88
Joined: Tue Oct 12, 2004 6:45 pm
Contact:
Thank u very much.
Mr. Arithmetic logic Unit

TISARKER
Learning poster
Posts: 88
Joined: Tue Oct 12, 2004 6:45 pm
Contact:
Thank u very much.
Mr. Arithmetic logic Unit

ayon
Experienced poster
Posts: 161
Joined: Tue Oct 25, 2005 8:38 pm

### 10917 - A Walk Through the Forest

plz clarify me something, i am getting tle. can this problem be solved using backtracking(dfs) within time-limit? output can be at most 2147483647. simply the program below run for near 3 sec in my computer

Code: Select all

``````void main()
{
int i;
for(i = 0; i < 2147483647; ++i)
;
}``````
which algorithm should be used for this problem with a better runtime? i used backtracking(dfs), i used adjacancy list, i pruned whenever a node is found before with a short distance. and one more question, can there be such any input, where a node is numdered with a value greater than n or less than 1? (n is the total number of nodes)
ishtiak zaman
----------------
the world is nothing but a good program, and we are all some instances of the program

mf
Guru
Posts: 1244
Joined: Mon Feb 28, 2005 4:51 am
Location: Zürich, Switzerland
Contact:
You can use Dijkstra to find a subgraph in which Jimmy may walk, then use dynamic programming to count paths in it.

ayon
Experienced poster
Posts: 161
Joined: Tue Oct 25, 2005 8:38 pm
why am i getting wa? i used dijkstra to find distance to all vertices. then i ran the following DP
n_path(dest) = summation of n_path(v), where v is adjacent to dest and distance[v] == distance[dest] - weight[v,dets], is this correct?

Code: Select all

``````#include <stdio.h>
#include <string.h>
#include <ctype.h>

struct
{
int d;
} list;

bool visited;

int extractMin()
{
int i, min = 2147483646, index = -1;
for(i = 0; i < n; ++i)
if(visited[i] == false && dist[i] != -1 && dist[i] < min)
{
min = dist[i];
index = i;
}
return index;
}

void dijkstra()
{
int i, u, v;
memset(dist, -1, sizeof(dist));
memset(visited, false, sizeof(visited));
dist = 0;
for(;;)
{
u = extractMin();
if(u != -1)
visited[u] = true;
else
break;
for(i = 0; i < n_adj[u]; ++i)
{
if(visited[v] == false && (dist[v] == -1 || dist[v] > dist[u] + list[u][i].d))
dist[v] = dist[u] + list[u][i].d;
}
}
}

int n_path(int u)
{
if(u == 0)
return 1;
if(memory[u] != -1)
return memory[u];
int i, count = 0, v;
for(i = 0; i < n_adj[u]; ++i)
{
if(dist[v] != -1 && dist[v] == dist[u] - list[u][i].d)
count += n_path(v);
}
return memory[u] = count;
}

bool exit(char s[], int &m)
{
int i, count = 0, prev = ' ';
for(i = 0; s[i]; ++i)
{
if(isdigit(s[i]) && !isdigit(prev))
++count;
prev = s[i];
}
if(count == 1)
{
sscanf(s, "%d", &n);
if(n == 0)
return true;
}
else if(count == 2)
{
sscanf(s, "%d%d", &n, &m);
return false;
}
else
n /= 0;
return false;
}

void main()
{
int m, x, y, d;
char s;
for(;;)
{
scanf(" %[^\n]", s);
if(exit(s, m))
break;
while(m--)
{
scanf("%d%d%d", &x, &y, &d);
--x;
--y;
}
dijkstra();
memset(memory, -1, sizeof(memory));
printf("%d\n", n_path(1));
}
}``````
i read the explanation of the page above, but i dont understand is there any necessity of topological sort?
ishtiak zaman
----------------
the world is nothing but a good program, and we are all some instances of the program

sclo
Guru
Posts: 519
Joined: Mon Jan 23, 2006 10:45 pm
Contact:
Try this:
Let d(u) be the distance between vertice u and 2.
then f(u) = sum of f(v) such that u,v are adjacent and d(v)<d(u)
where f(u) is the number of path from u to 2

shakil
Learning poster
Posts: 74
Joined: Sat Jul 15, 2006 6:28 am
Contact:

### Why WA...

Code: Select all

``cut after AC``
Last edited by shakil on Fri May 11, 2007 7:52 am, edited 1 time in total.
SHAKIL

Jan
Guru
Posts: 1334
Joined: Wed Jun 22, 2005 10:58 pm
Contact:
Try the cases.

Input:

Code: Select all

``````6 11
1 6 2995
6 3 4827
3 1 32391
1 3 153
3 5 12382
5 4 18716
4 3 19895
3 6 21726
6 1 1869
1 5 25667
5 2 17035
10 8
1 4 16803
4 8 6286
8 1 28531
1 10 10722
10 3 22946
3 8 24230
8 6 30570
6 2 19832
0``````
Output:

Code: Select all

``````3
2``````
Hope these help.
Ami ekhono shopno dekhi...
HomePage

shakil
Learning poster
Posts: 74
Joined: Sat Jul 15, 2006 6:28 am
Contact:
Jan , thanks for help me.Your data really helped me.
SHAKIL

shihabrc
New poster
Posts: 49
Joined: Sun Sep 18, 2005 10:20 am
Location: CSE,BUET
Contact:

### lots of WA

What i've done is:

1. Find shortest path from 2 to all vertex using dijkstra
2. build another di graph with edges (u,v) such that d > d[v] in the original graph. that is length of any path from v to 2 is shorter than length of any path from u to 2;
3. count the number of paths from 1 to 2 in the new graph using BFS.

I'm getting WA with this approach. This code passes the inputs given in this post.Can some1 give me some I/O , suggetions plz.

Code: Select all

``````

#include <stdio.h>
#include <vector>
#include <queue>
#include <functional>
#include <string.h>

using namespace std;

#define MAXN	1005
#define INF		999999999

typedef struct node_
{
int u,cost;
} node_;

bool operator < (node_ a,node_ b){ return a.cost > b.cost; }
bool operator > (node_ a,node_ b){ return a.cost < b.cost; }
bool operator == (node_ a,node_ b){ return a.cost == b.cost; }

int v,E;
int d[MAXN],path[MAXN];
bool visited[MAXN];
priority_queue <node_> PQ;

void dijkstra(int s)
{
int i;
node_ u,next;

for( i = 1; i <= v; i++ )
{
d[i] = INF;
visited[i] = false;
}

d[s] = 0;
u.u = s,u.cost = 0;
while(!PQ.empty()) PQ.pop();
PQ.push(u);

while(!PQ.empty())
{
u = PQ.top();
PQ.pop();

if( visited[u.u] ) continue;
visited[u.u] = true;

for( i = 0; i < adj[u.u].size(); i++ )
{

if( !visited[next.u] )
{
if( d[next.u] > d[u.u] + next.cost )
{
d[next.u] = d[u.u] + next.cost;
PQ.push(next);
}
}
}

}
}

void rebuildGraph()
{
int i,j;
node_ u;

for( i = 1; i <= v; i++ )
{
for( j = 0; j < adj[i].size(); j++ )
{
if( d[i] > d[u.u] ) newAdj[i].push_back(u.u);
}
}
}

void countPath()
{
int i,u,next;
queue <int> Q;
memset(visited,false,sizeof(visited));
memset(path,0,sizeof(path));
path = 1,visited = true;
Q.push(1);

while(!Q.empty())
{
u = Q.front();
Q.pop();

for( i = 0; i < newAdj[u].size(); i++ )
{
if( !visited[next] )
{
visited[next] = true;
path[next] = path[u];
Q.push(next);
}
else path[next] += path[u];
}
}
}

int main()
{
int i,m,n,w;
node_ push;

while(scanf("%d",&v) == 1 && v)
{
scanf("%d",&E);

for( i = 1; i <= v; i++ ) adj[i].clear();

for( i = 0; i < E; i++ )
{
scanf("%d %d %d",&m,&n,&w);
push.u = n;push.cost = w;
}

dijkstra(2);
rebuildGraph();
countPath();
printf("%d\n",path);
}

return 0;
}

``````
Shihab
CSE,BUET

Anindya
New poster
Posts: 28
Joined: Sun Feb 04, 2007 4:34 am
Location: EEE,BUET,DHAKA
Sclo wrote:
Try this:
Let d(u) be the distance between vertice u and 2.
then f(u) = sum of f(v) such that u,v are adjacent and d(v)<d(u)
where f(u) is the number of path from u to 2
I have implemented this & getting WA.
This is my function :

Code: Select all

``````int f(int u)
{
int cnt=0,v;
if(u==2)
return 1;
if(ct[u]>=0)
return ct[u];
for(v=1;v<=n;v++)
if(mat[v][u]<inf && dist[v]<dist[u])
cnt+=f(v);
ct[u]=cnt;
return ct[u];
}``````
Here ct is the number of paths from u to 2.
dist is the distance from 2 to u.
Have i understood something wrong?

& i think Jan's 1st set of input is wrong because :
There is at most one path between any pair of intersections.

I have checked that there is no such input in which there is more than one pair of inputs between any pair of nodes.

Anindya
New poster
Posts: 28
Joined: Sun Feb 04, 2007 4:34 am
Location: EEE,BUET,DHAKA
Oh that was fully because of a small mistake in the implementation of dijkstra. Now got AC Jan's first set of output should be like this:

Code: Select all

``````6 9
1 6 2995
6 3 4827
3 1 32391
3 5 12382
5 4 18716
4 3 19895
6 1 1869
1 5 25667
5 2 17035``````
Ouput is the same as given by him.