Page 10 of 11
Re: 10000 - Longest Path
Posted: Wed Dec 24, 2008 3:07 pm
by mf
ashish_thakur wrote:Thanks , Now I am getting TL error
If you want to hear my opinion on your new TL code, you have to post it again. Or edit your previous post and update the code there.
is there any standard algo for this type of problem
One linear-time algorithm is to topologically sort the graph and then do usual dynamic programming on it. This can be implemented very compactly with DFS, in pseudocode:
Code: Select all
dfs(x): // does depth-first search, and returns length of longest path starting at x
if x was previously visited:
return the previously recorded return value of dfs(x).
res = 0;
for every edge x->y, do:
res = max(res, 1 + dfs(y));
mark vertex x as visited, and record res in some array as return value of dfs(x)
return res
Another algorithm that would work here, given the very low constraints (n<=100), and is very easy to implement is Floyd-Warshall algorithm. Normally, it is used to find shortest paths, to find the longest paths in DAGs just change the 'min' function in it to 'max'. (or, equivalently, negate the edge costs)
Re: 10000 - Longest Path
Posted: Wed Dec 24, 2008 6:11 pm
by ashish_thakur
here is the code with TL error
Code: Select all
#include<stdio.h>
#include<stdlib.h>
struct node{
int value;
struct node * next;
};
int numNodes;
int largestDepth;
VISIT(struct node **Node, int n){
static int depth=0;
struct node *NODE = Node[n];
while(NODE!=0){
++depth;
VISIT(Node,NODE->value);
NODE=NODE->next;
}
if(depth>largestDepth)
largestDepth=depth;
depth=0;
}
int main(void){
int caseNo=1;
while(1){
int startNode;
scanf("%d",&numNodes);
if(numNodes<1)break;
scanf("%d",&startNode);
struct node *Node[numNodes+1];
int i;
for(i=1;i<numNodes+1;i++){
Node[i]=0;
}
int p,q;
while(1){
scanf("%d",&p);
scanf("%d",&q);
if(p==0 && q==0)
break;
if(Node[p]==0){
Node[p] = (struct node *)malloc(sizeof (struct node));
Node[p]->value=q;
Node[p]->next=0;
}else{
struct node * head=Node[p];
while(head->next!=0){
head=head->next;
}
struct node * new= (struct node *)malloc(sizeof (struct node));
new->value=q;
new->next=head;
head->next=new;
new->next=0;
}
}
VISIT(Node,startNode);
printf("Case %d: The longest path from %d has length %d finishing at %d.\n",caseNo,startNode, largestDepth,2);
largestDepth=0;
caseNo++;
}
}
Re: 10000 - Longest Path
Posted: Wed Dec 24, 2008 6:27 pm
by mf
Just implement one of the algorithms already mentioned in this thread.
What you do - brute-forcing all possible paths - is not fast enough, simply because there can be too many such paths. For example, in the worst possible input case when n=100 and the graph has n(n-1)/2 edges, there are about 10^30 paths - an astronomic number!
Re: 10000 - Longest Path
Posted: Sat Dec 27, 2008 8:45 pm
by ashish_thakur
Hello I tried but I am geting RE with the modified changes please help me out
Code: Select all
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node{
int value;
struct node * next;
};
int numNodes;
int largestDepth;
void VISIT(struct node **Node, int n,int *visit,int *f){
struct node *NODE = Node[n];
if(visit[n-1]==1) // if visited return
return;
visit[n-1]=1;
static int depth;
depth=0;
while(NODE!=0){
if(visit[NODE->value-1]==1)
f[n-1]= f[n-1]>1+f[NODE->value-1]?f[n-1]:1+f[NODE->value-1];
else
VISIT(Node,NODE->value,visit,f);
NODE=NODE->next;
f[n-1]=f[n-1]>=depth?f[n-1]:depth;
}
if(f[n-1]>=depth)
depth=f[n-1]+1;
else{
f[n-1]=depth;
depth+=1;
}
}
int main(void){
int caseNo=1;
while(1){
int startNode;
scanf("%d",&numNodes);
if(numNodes<1)break;
scanf("%d",&startNode);
struct node *Node[numNodes+1]; // to store all the nodes from 1 to numNodes
int i;
int VISITED[numNodes]; // to store visited info
int f[numNodes]; // to store final longest distance from each node
memset(f,0,sizeof(int)*numNodes);
memset(VISITED,0,sizeof(int)*numNodes);
for(i=1;i<numNodes+1;i++){
Node[i]=0;
}
int p,q;
while(1){ // creating adjacency list of all the nodes
scanf("%d",&p);
scanf("%d",&q);
if(p==0 && q==0)
break;
if(Node[p]==0){
Node[p] = (struct node *)malloc(sizeof (struct node));
Node[p]->value=q;
Node[p]->next=0;
}else{
struct node * head=Node[p];
while(head->next!=0){
head=head->next;
}
struct node * new= (struct node *)malloc(sizeof (struct node));
new->value=q;
new->next=head;
head->next=new;
new->next=0;
}
}
VISIT(Node,startNode,VISITED,f);
printf("Case %d: The longest path from %d has length %d finishing at %d. \n",caseNo,startNode,f[startNode-1],2);
caseNo++;
}
}
Re: 10000 - Longest Path
Posted: Sun Dec 28, 2008 10:24 am
by ashish_thakur
Ok I got it return 0 was missing in main
Re: 10000 - Longest Path
Posted: Sun Mar 29, 2009 8:56 am
by vahid sanei
Code: Select all
REMOVED
Just I change table[101][101] to table[103][103] and got Acc
Re: 10000 - Longest Path
Posted: Sun Oct 11, 2009 9:10 pm
by Skt
#include<iostream>
#include<queue>
using namespace std;
int dist[103],maxi;
bool G[103][103];
void bfs(int node);
int main()
{
bool one = 0;
int j,i,r,c,p,q,source,pos,ans,kase = 1;
while(cin>>maxi && maxi)
{
for(i=0;i<maxi;i++) for(j = 0;j<maxi;j++) G[j] = 0;
for(i=0;i<maxi;i++) dist = 0;
cin>>source;
while(cin>>p>>q && (p||q))
G[p-1][q-1] = 1;
bfs(source-1);
ans = 0;
for(i=0;i<maxi;i++)
if(dist>ans) {pos = i+1;ans = dist;}
if(one == 1)cout<<endl<<endl;
one = 1;
cout<<"Case "<<kase++<<": The longest path from "<<source<<" has length "<<ans<<", finishing at "<<pos<<".\n";
}
return 0;
}
void bfs(int node)
{
int i,start;
queue<int> q;q.push(node);
while(!q.empty())
{
start = q.front();q.pop();
for(i=0;i<maxi;i++)
{
if(G[start] == 1 )
{
q.push(i);
dist = dist>dist[start] + 1 ? dist : dist[start]+1;
}
}
}
}
why am i getin TLE ????
Re: 10000 - Longest Path
Posted: Wed Oct 14, 2009 8:00 pm
by arifcsecu
Since vertex is 100
SO you can use Floyd warshall algorithm
hope it helps
Re: 10000 - Longest Path
Posted: Wed Dec 23, 2009 12:41 am
by amishera
Hi,
My code is getting time limit exceeded. The core logic is below:
Code: Select all
[b]path_info find_longest(int s, int visited_nodes[], linked_list* adj_list[MAX_NODES], int n)
{
// make current node s visted
visited_nodes[s] = 1;
int max = 0;
int dest = s;
// for each of its neibhors find the longest path
for (linked_list* p = adj_list[s];p != NULL;p = p->next)
{
int i = p->value;
if (visited_nodes[i] == 0)
{
path_info t = find_longest(i, visited_nodes, adj_list, n);
if (t.max+1 > max)
{
max = t.max+1;
dest = t.destination;
}
else if (t.max+1 == max)
{
dest = (dest < t.destination) ? dest : t.destination;
}
}
}
// then find the longest among the neighbors
visited_nodes[s] = 0;
path_info p;
p.max = max;
p.destination = dest;
return p;
}
[/b]
And the complete code is:
Code: Select all
#include <stdio.h>
#include <stdlib.h>
#define MAX_NODES 100
typedef struct _path_info
{
int max;
int destination;
} path_info;
typedef struct tag_linked_list linked_list;
struct tag_linked_list
{
int value;
linked_list* next;
};
void list_insert(linked_list** lst, int x)
{
// create a new node
linked_list* node = (linked_list*) malloc(sizeof(linked_list));
node->value = x;
node->next = *lst;
// make it the new head
*lst = node;
}
void initialize_adj_list(linked_list* adj_list[], int n)
{
for (int i = 0;i < n;i++)
{
adj_list[i] = NULL;
}
}
[b]path_info find_longest(int s, int visited_nodes[], linked_list* adj_list[MAX_NODES], int n)
{
// make current node s visted
visited_nodes[s] = 1;
int max = 0;
int dest = s;
// for each of its neibhors find the longest path
for (linked_list* p = adj_list[s];p != NULL;p = p->next)
{
int i = p->value;
if (visited_nodes[i] == 0)
{
path_info t = find_longest(i, visited_nodes, adj_list, n);
if (t.max+1 > max)
{
max = t.max+1;
dest = t.destination;
}
else if (t.max+1 == max)
{
dest = (dest < t.destination) ? dest : t.destination;
}
}
}
// then find the longest among the neighbors
visited_nodes[s] = 0;
path_info p;
p.max = max;
p.destination = dest;
return p;
}
[/b]
void free_linked_list(linked_list* lst)
{
if (lst != NULL)
{
free_linked_list(lst->next);
free(lst);
}
}
void destroy_adj_list(linked_list* adj_list[], int n)
{
for (int i = 0;i < n;i++)
{
free_linked_list(adj_list[i]);
}
}
int get_inputs(int* n, int* s, linked_list* adj_list[])
{
scanf(" %d",n);
// check exit condition
if (*n == 0)
{
return 1;
}
scanf(" %d",s);
initialize_adj_list(adj_list, *n);
int p,q;
while (1)
{
scanf(" %d %d",&p,&q);
if (p == 0 && q == 0)
{
break;
}
list_insert(&adj_list[p-1], q-1);
}
}
int main()
{
int counter = 0;
int is_first = 1;
while (1)
{
int n;
int s;
linked_list *adj_list[MAX_NODES];
// take inputs
// check exit condition
if (get_inputs(&n, &s, adj_list))
{
break;
}
// find the longest path recursively
int visited_nodes[MAX_NODES];
for (int i = 0;i < n;i++)
{
visited_nodes[i] = 0;
}
path_info path = find_longest(s-1, visited_nodes, adj_list, n);
counter++;
if (is_first)
{
is_first = 0;
}
else
{
printf("\n");
}
printf("Case %d: The longest path from %d has length %d, finishing at %d.\n",counter, s, path.max, path.destination+1);
//destroy_adj_list(adj_list, n);
}
return 0;
}
What the find_longest is doing is for a given node finding whether it has some neighbors and for each neighbor finding the longest path recursively. whenever a recursive call is made, the current node marks itself as visited by setting the array visited_nodes[s] = 1 and upon exit setting the array visited[s] = 0 so that this node can be reached via other nodes in a different path to get a different length. To prevent cycles, visited_nodes keep track of the nodes already encounted along the path (by setting visited_nodes[1]) and by checking visited_nodes
== 0 we explore a not visited node.
Is my logic correct or something is not right here?
Some help would be greatly appreciated.
Thanks.
Re: 10000 - why runtime error ?
Posted: Fri Aug 06, 2010 8:03 am
by @mjad
anybody help me why runtime error?
i think this is right.
please help me
Code: Select all
#include<iostream>
using namespace std;
void compare(int a[100][2],int idx,int n);
int t=-1,ix=-1;
int main()
{
int node,start,n1,n2,i,j,search[100][2],index[100],ks=0;
//freopen("10000input.txt","r",stdin);
while(1)
{
i=0;j=0;
cin>>node;
if(node==0)
break;
cin>>start;
while(1)
{
cin>>n1>>n2;
if(n1==0||n2==0)
break;
if(start==n1)
index[j++]=i;
search[i][0]=n1;
search[i][1]=n2;
i++;
}
while(j)
{
j--;
compare(search,index[j],i);
}
cout<<"Case "<<++ks<<": The longest path from "<<start<<" has length "<<t<<", finishing at "<<ix<<"."<<endl<<endl;
t=-1;ix=-1;
}
return 0;
}
void compare(int a[100][2],int idx,int n)
{
int i=0,c=1;
for(;i<n;i++)
{
if(a[i][0]==a[idx][1])
{
c++;
idx=i;
i=0;
}
}
if(c>t||((c==t)&&(ix>a[idx][1])))
{
t=c;
ix=a[idx][1];
}
}
Re: 10000 - Longest Path
Posted: Wed Sep 01, 2010 12:23 am
by arifcsecu
please
increase your array size
for 100 to 101 or more ..
hints: Why did you not use Floyd Warshall Algorithm ? it has an easy solution with simple floyd warshall algorithmm
Re: 10000 - Longest Path
Posted: Sat Dec 17, 2011 7:54 pm
by littleibex
Hi..I am getting TLE...can anybody help me out please..here is my code
Code: Select all
#include <iostream>
#include <sstream>
using namespace std;
int max1, max2, pl;
bool map[110][110];
void go(int s, int n)
{
for(int j = 1; j <= n; j ++)
{
if(map[s][j])
{
max2 ++;
go(j, n);
}
}
if(max2 > max1 || (max1 == max2 && s < pl))
{
max1 = max2;
pl = s;
}
max2 --;
}
int main()
{
int n, s, paths, a, b;
stringstream ss;
for(int x = 1; true; x ++)
{
cin >> n;
if(n == 0)
{
break;
}
cin >> s;
paths = 0;
ss.str("");
for( ; true; )
{
cin >> a >> b;
if(a == 0 && b == 0)
{
break;
}
paths ++;
ss << a << " " << b << endl;
}
int p[paths], q[paths];
for(int i = 0; i < paths; i ++)
{
ss >> p[i] >> q[i];
}
for(int i = 0; i <= n; i ++)
{
for(int j = 0; j <= n; j ++)
{
map[i][j] = false;
}
}
for(int i = 0; i < paths; i ++)
{
map[p[i]][q[i]] = true;
}
pl = n + 1;
max1 = 0;
max2 = 0;
go(s, n);
cout << "Case " << x << ": The longest path from " << s << " has length " << max1 << ", finishing at " << pl << ".\n\n";
}
return 0;
}
Thanks in advance
Re: 10000 - Longest Path
Posted: Tue Jan 10, 2012 1:14 am
by brianfry713
littleibex try using the Floyd Warshall algorithm.
Re: 10000 - Longest Path
Posted: Sun Jul 01, 2012 5:14 pm
by SyFy
got ac with FW ... but before that got 4 WAs 'cause I forgot to print \n\n after each line of output.
it should be something like this: out.printf("Case 1: The longest path from 1 has length 2, finishing at 4.\n\n");
good luck!

Re: 10000 - Longest Path
Posted: Thu Aug 02, 2012 7:54 am
by gtg_bansal
Getting TLE .
This is my first submission on UVA and I am getting TLE. I am using BFS and assuming directed tree.
Please help
Code: Select all
#include<stdio.h>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
int main()
{
int nodes,cases=0;
scanf("%d", &nodes);
while(nodes!=0){
cases++;
int start;
scanf("%d", &start);
int a[102][102],meta[102];
//memset(a,0,(nodes+1)*(nodes+1)*sizeof(int));
memset(meta,0,(nodes+1)*sizeof(int));
// vector< vector<int> > a(102,vector<int>(0,0));
int p, qq;
scanf("%d%d", &p,&qq);
while(p!=0){
a[p][meta[p]++]=qq;
scanf("%d%d", &p,&qq);
}
queue<int> q;
int dist[102],max,index;
max=index=0;
memset(dist,0,(nodes+1)*sizeof(int));
q.push(start);
while(!q.empty()){
int n = q.front();
q.pop();
for(int i=0;i<meta[n];i++){
int jj=a[n][i];
q.push(jj);
dist[jj]=dist[n]+1;
if(index>jj && dist[jj]==max)
index=jj;
if(dist[jj]>max){
max=dist[jj];
index = jj;
}
}
}
printf("Case %d: The longest path from %d has length %d, finishing at %d.\n", cases,start,max,index);
scanf("%d", &nodes);
}
return 0;
}