题意:有向无环图,给n个点,给一个起点,给许多条有向边(输入到0,0,每条边边权为1)。求从起点出发,最远能走到多远。记录起点到最远那个点的距离以及点坐标。
我的做法:
1.dfs+剪枝,记录一个深度,记录最大深度和对应坐标就行了。不过就这样dfs的话会TLE,需要记录从起点到每个点的最远距离,如果跑过来的距离小于之前到达这个点的距离,就不跑了。
2.spfa,一直往大的更新就行了。
最长路径只能做这种没有环的,如果有正环的话,dfs已经不考虑了,spfa的话考虑加个标记数组记录进队次数来判断正环。
1
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e5;
const int N = 200;
struct node{
int v,next;
}E[N*N];
int n,top;
int head[N];
int dis[N]; ///走到这个点最远距离是多少
void Init()
{
top = 0;
for(int i = 0;i < N;i++){
dis[i] = -1;
head[i] = -1;
}
}
void add(int u,int v)
{
E[top].v = v;
E[top].next = head[u];
head[u] = top++;
}
int en,ansdep;
void dfs(int u,int dep)
{
if(dep > dis[u]) dis[u] = dep;
else return; ///如果走到这个点的距离比之前更短就没必要走了。(这里不减就TLE
if(dep > ansdep){
en = u;
ansdep = dep;
}
else if(dep == ansdep)
en = min(en,u);
for(int i = head[u];i != -1;i = E[i].next){
int v = E[i].v;
dfs(v,dep+1);
}
}
int main(void)
{
int cas = 1;
while(scanf("%d",&n) && n){
Init();
int st;
scanf("%d",&st);
int u,v;
while(scanf("%d%d",&u,&v) && (u||v)){
add(u,v);
}
en = st;
ansdep = 0;
dfs(st,0);
printf("Case %d: The longest path from %d has length %d, finishing at %d.\n\n",cas++,st,ansdep,en);
}
return 0;
}
2
#include <bits/stdc++.h>
using namespace std;
const int N = 200;
struct node{
int v,next;
}E[N*N];
int n,top;
int head[N]; ///头结点
int dis[N]; ///距离
int vis[N]; ///spfa的标记数组
void Init()
{
top = 0;
for(int i = 0;i < N;i++){
head[i] = -1;
vis[i] = false;
dis[i] = 0;
}
}
void add(int u,int v)
{
E[top].v = v;
E[top].next = head[u];
head[u] = top++;
}
void spfa(int st)
{
dis[st] = 0;
vis[st] = true;
queue<int> q;
q.push(st);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u];i != -1;i = E[i].next){
int v = E[i].v;
if(dis[v] < dis[u]+1){ ///一直按着大的走就行了
dis[v] = dis[u]+1;
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
}
int main(void)
{
int cas = 1;
while(scanf("%d",&n) && n){
Init();
int st;
scanf("%d",&st);
int u,v;
while(scanf("%d%d",&u,&v) && (u||v)){
add(u,v);
}
spfa(st);
int dep = 0,en;
for(int i = n;i >= 1;i--)
if(dis[i] >= dep) dep = dis[i],en = i;
printf("Case %d: The longest path from %d has length %d, finishing at %d.\n\n",cas++,st,dep,en);
}
return 0;
}