题目:给出一个图和图上的边(边长为1),求最长路径,图中无回路。
分析:最短路、图论。
方案1,拓扑排序求关键路径+dp。做一次拓扑排序即可,求出逻辑关系,利用dp更新路径长度。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
int maps[105][105];
int used[105];
int stack[105];
int times[105];
int Count;
void dfs( int s, int n )
{
for ( int i = 1 ; i <= n ; ++ i )
if ( !used[i] && maps[s][i] ) {
used[i] = 1;
dfs( i, n );
}
stack[Count ++] = s;
}
void topological( int s, int n )
{
for ( int i = 1 ; i <= n ; ++ i ) {
used[i] = 0;
times[i] = -10005;
}
times[s] = 0;
used[s] = 1;
Count = 0;
dfs( s, n );
int max = s;
for ( int i = Count-1 ; i >= 0 ; -- i )
for ( int j = Count-1 ; j > i ; -- j ) {
int a = stack[i],b = stack[j];
if ( maps[b][a] && times[a] <= times[b] + 1 ) {
times[a] = times[b] + 1;
if ( times[max] == times[a] && a < max )
max = a;
else if ( times[max] < times[a] )
max = a;
}
}
printf("%d, finishing at %d.\n\n",times[max],max);
}
int main()
{
int n,s,p,q,t = 1;
while ( scanf("%d",&n) && n ) {
scanf("%d",&s);
memset( maps, 0, sizeof(maps) );
while ( scanf("%d%d",&p,&q) && p+q )
maps[p][q] = 1;
printf("Case %d: The longest path from %d has length ",t ++,s);
topological( s, n );
}
return 0;
}
方案2:边长取-1则变成无负权回路状态下的最短路问题。利用spfa(bellman-ford)求最短路。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
int maps[105][105];
int visit[105];
int dist[105];
int stack[105];
void spfa( int s, int n )
{
for ( int i = 1 ; i <= n ; ++ i ) {
visit[i] = 0;
dist[i] = 0;
}
int top = 0;
stack[top ++] = s;
visit[s] = 1;
dist[s] = 0;
while ( top -- ) {
int now = stack[top];
for ( int i = 1 ; i <= n ; ++ i )
if ( maps[now][i] && dist[i] > dist[now] - 1 ) {
dist[i] = dist[now] - 1;
if ( !visit[i] ) {
visit[i] = 1;
stack[top ++] = i;
}
}
visit[now] = 0;
}
int space = 1;
for ( int i = 1 ; i <= n ; ++ i )
if ( dist[i] < dist[space] )
space = i;
printf("%d, finishing at %d.\n\n",-1*dist[space],space);
}
int main()
{
int n,s,p,q,t = 1;
while ( scanf("%d",&n) && n ) {
scanf("%d",&s);
memset( maps, 0, sizeof(maps) );
while ( scanf("%d%d",&p,&q) && p+q )
maps[p][q] = 1;
printf("Case %d: The longest path from %d has length ",t ++,s);
spfa( s, n );
}
return 0;
}