Page **1** of **2**

### 10917 - Walk Through the Forest

Posted: **Mon Oct 03, 2005 9:43 pm**

by **TISARKER**

I have collected Input for this problem from website.

But I can not check it.Because I have used long type array[1000][1000].

Which is not suported by my visual c++ compiler.

Please give me a good advise.

I am waiting.

Posted: **Tue Oct 04, 2005 8:55 am**

by **TISARKER**

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[1000][1000] in uva judge?"

Posted: **Tue Oct 04, 2005 10:15 am**

by **wook**

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[1000][1000] 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.

Posted: **Fri Oct 07, 2005 7:02 pm**

by **TISARKER**

Thank u very much.

Posted: **Fri Oct 07, 2005 7:03 pm**

by **TISARKER**

Thank u very much.

### 10917 - A Walk Through the Forest

Posted: **Thu Jan 19, 2006 10:51 pm**

by **ayon**

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)

Posted: **Thu Jan 19, 2006 11:09 pm**

by **mf**

You can use Dijkstra to find a subgraph in which Jimmy may walk, then use dynamic programming to count paths in it.

Also, read explanation at this page

http://www.algorithmist.com/index.php/UVa_10917

Posted: **Thu Jun 08, 2006 9:20 am**

by **ayon**

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 adj;
int d;
} list[1009][1009];
int n, n_adj[1009], dist[1009], memory[1009];
bool visited[1009];
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] = 0;
for(;;)
{
u = extractMin();
if(u != -1)
visited[u] = true;
else
break;
for(i = 0; i < n_adj[u]; ++i)
{
v = list[u][i].adj;
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)
{
v = list[u][i].adj;
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[100];
for(;;)
{
scanf(" %[^\n]", s);
if(exit(s, m))
break;
memset(n_adj, 0, sizeof(n_adj));
while(m--)
{
scanf("%d%d%d", &x, &y, &d);
--x;
--y;
list[x][n_adj[x]].adj = y;
list[x][n_adj[x]++].d = d;
list[y][n_adj[y]].adj = x;
list[y][n_adj[y]++].d = d;
}
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?

Posted: **Mon Aug 28, 2006 2:31 am**

by **sclo**

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

### Why WA...

Posted: **Thu May 10, 2007 7:18 pm**

by **shakil**

Why WA please help. Can someone give me more input and output.

Posted: **Thu May 10, 2007 8:49 pm**

by **Jan**

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:**
Hope these help.

Posted: **Fri May 11, 2007 7:55 am**

by **shakil**

Jan , thanks for help me.Your data really helped me.

### lots of WA

Posted: **Fri May 18, 2007 11:24 pm**

by **shihabrc**

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;
vector <node_> adj[MAXN];
vector <int> newAdj[MAXN];
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++ )
{
next = adj[u.u][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++ )
{
newAdj[i].clear();
for( j = 0; j < adj[i].size(); j++ )
{
u = adj[i][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] = 1,visited[1] = true;
Q.push(1);
while(!Q.empty())
{
u = Q.front();
Q.pop();
for( i = 0; i < newAdj[u].size(); i++ )
{
next = newAdj[u][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;
adj[m].push_back(push);push.u = m;
adj[n].push_back(push);
}
dijkstra(2);
rebuildGraph();
countPath();
printf("%d\n",path[2]);
}
return 0;
}
```

Posted: **Fri Feb 01, 2008 8:52 am**

by **Anindya**

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.

Posted: **Sat Feb 02, 2008 8:07 pm**

by **Anindya**

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.