相当与一个拓扑排序的模板题吧

蒟蒻的辛酸史

题目大意:给你一个有向无环图,让你求出1到n的最长路,如果没有路径,就输出-1

思路:一开始以为是一个很裸的拓扑排序

就不看题目,直接打了一遍拓扑排序

然后就得到了45分的成绩

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define int long long int using namespace std; struct node
{
int u;
int v;
int w;
int next;
}data[];
int head[];
int cnt;
int n,m; inline void add(int u,int v,int w)
{
cnt++;
data[cnt].v=v;
data[cnt].w=w;
data[cnt].next=head[u];
head[u]=cnt;
} queue<int> q;
int fl[];
int value[]; signed main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
fl[v]++;
}
for(int i=;i<=n;i++)
{
if(fl[i]==)
{
q.push(i);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=data[i].next)
{
if(value[data[i].v]<value[x]+data[i].w)
{
value[data[i].v]=value[x]+data[i].w;
}
fl[data[i].v]--;
if(!fl[data[i].v])
{
q.push(data[i].v);
}
}
}
int ans=;
for(int i=;i<=n;i++)
{
ans=max(ans,value[i]);
}
cout<<ans<<endl;
return ; }

45分代码

读题,加上了-1

得到了56分的好成绩

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define int long long int using namespace std; struct node
{
int u;
int v;
int w;
int next;
}data[];
int head[];
int cnt;
int n,m; inline void add(int u,int v,int w)
{
cnt++;
data[cnt].v=v;
data[cnt].w=w;
data[cnt].next=head[u];
head[u]=cnt;
} queue<int> q;
int fl[];
int value[]; signed main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
fl[v]++;
}
for(int i=;i<=n;i++)
{
if(fl[i]==)
{
q.push(i);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=data[i].next)
{
if(value[data[i].v]<value[x]+data[i].w)
{
value[data[i].v]=value[x]+data[i].w;
}
fl[data[i].v]--;
if(!fl[data[i].v])
{
q.push(data[i].v);
}
}
}
int ans=;
for(int i=;i<=n;i++)
{
ans=max(ans,value[i]);
}
if(ans==)
{
cout<<-<<endl;
}
else cout<<ans<<endl;
return ; }

56分代码

问了问lzt大佬

他说什么求的是1到n的最长路,而不是整张图中的最长路。。

修改,期望得分100

实际得分:67

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define int long long int using namespace std; struct node
{
int u;
int v;
int w;
int next;
}data[];
int head[];
int cnt;
int n,m; inline void add(int u,int v,int w)
{
cnt++;
data[cnt].v=v;
data[cnt].w=w;
data[cnt].next=head[u];
head[u]=cnt;
} queue<int> q;
int fl[];
int value[]; signed main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
fl[v]++;
}
for(int i=;i<=n;i++)
{
if(fl[i]==)
{
q.push(i);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=data[i].next)
{
if(value[data[i].v]<value[x]+data[i].w)
{
value[data[i].v]=value[x]+data[i].w;
}
fl[data[i].v]--;
if(fl[data[i].v]==)
{
q.push(data[i].v);
}
}
}
int ans=;
for(int i=;i<=n;i++)
{
ans=max(ans,value[i]);
}
if(ans==)
{
cout<<-<<endl;
}
else cout<<value[n]<<endl;
return ; }

67分代码

继续问lzt大佬,

说什么要先删边再求

也就是说,在整张图中,可能存在很多入度为零的点

此时我们就需要删边(因为求1到n的最长路,和那些不是一的点有什么关系呢??)

打个比方:如果你不删边,也不处理那些入度为零的点

就好比你想知道你谈的恋爱中哪场谈的最久,如果不处理,就成了你和你的所有前女友中,你们谈的所有恋爱中时间最久的那个。

也就是你求你谈的最长的一场恋爱,和你前女友们谈的最长的恋爱不是一个东西

好,那么我们先把除了1之外入度为零的点都放进去

跑一边拓扑排序,就达到了删边的目的

然后再把一放入队列中,进行第二遍拓扑排序

这时,到达n的最长路就是1到n的最长路

期望得分100

实际得分89..

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define int long long int using namespace std; struct node
{
int u;
int v;
int w;
int next;
}data[];
int head[];
int cnt;
int n,m; inline void add(int u,int v,int w)
{
cnt++;
data[cnt].v=v;
data[cnt].w=w;
data[cnt].next=head[u];
head[u]=cnt;
} queue<int> q;
int fl[];
int value[]; signed main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
fl[v]++;
}
for(int i=;i<=n;i++)
{
if(fl[i]==)
{
q.push(i);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=data[i].next)
{
fl[data[i].v]--;
if(fl[data[i].v]==)
{
q.push(data[i].v);
}
}
}
q.push();
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=data[i].next)
{
if(value[data[i].v]<value[x]+data[i].w)
{
value[data[i].v]=value[x]+data[i].w;
}
fl[data[i].v]--;
if(fl[data[i].v]==)
{
q.push(data[i].v);
}
}
}
int ans=;
for(int i=;i<=n;i++)
{
ans=max(ans,value[i]);
}
if(ans==)
{
cout<<-<<endl;
}
else cout<<value[n]<<endl;
return ; }

89分代码

错在哪里了呢??

再仔细读一遍代码

发现特判-1的地方写错了

ans==0是指整张图中的最长路是零

但是并不是说明了1到n之间有路

然后我们就特判一下,如果value[n]==0

那么我们就输出-1

这是因为,当ans>0时,只是说明了图中有点相连,并没有说明1到n之间有路可走

这时我们特判一下,当其是零的时候,就说明了没有路可走,那么我们就输出-1

期望得分100

实际得分100

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define int long long int using namespace std; struct node
{
int u;
int v;
int w;
int next;
}data[];
int head[];
int cnt;
int n,m; inline void add(int u,int v,int w)
{
cnt++;
data[cnt].v=v;
data[cnt].w=w;
data[cnt].next=head[u];
head[u]=cnt;
} queue<int> q;
int fl[];
int value[]; signed main()
{
cin>>n>>m;
for(int i=;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
fl[v]++;
}
for(int i=;i<=n;i++)
{
if(fl[i]==)
{
q.push(i);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=data[i].next)
{
fl[data[i].v]--;
if(fl[data[i].v]==)
{
q.push(data[i].v);
}
}
}
q.push();
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=data[i].next)
{
if(value[data[i].v]<value[x]+data[i].w)
{
value[data[i].v]=value[x]+data[i].w;
}
fl[data[i].v]--;
if(fl[data[i].v]==)
{
q.push(data[i].v);
}
}
}
int ans=;
for(int i=;i<=n;i++)
{
ans=max(ans,value[i]);
}
if(ans==||value[n]==)
{
cout<<-<<endl;
}
else cout<<value[n]<<endl;
return ; }

100分代码

洛谷 P1807 最长路_NOI导刊2010提高(07)题解的更多相关文章

  1. 洛谷 P1807 最长路_NOI导刊2010提高(07) 题解

    P1807 最长路_NOI导刊2010提高(07) 题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算 ...

  2. 洛谷 P1807 最长路_NOI导刊2010提高(07)

    最长路 #include <iostream> #include <cstdio> #include <cstring> #include <queue> ...

  3. 洛谷P1807 最长路_NOI导刊2010提高(07)

    //拓扑排序求最长路 #include<bits/stdc++.h> #include<queue> using namespace std; const int INF=0x ...

  4. 图论--最长路--洛谷P1807 最长路_NOI导刊2010提高(07)

    题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入格式 ...

  5. luogu P1807 最长路_NOI导刊2010提高(07)

    题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入格式 ...

  6. P1807 最长路_NOI导刊2010提高(07)

    题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入输出 ...

  7. 【luogu P1807 最长路_NOI导刊2010提高(07)】 题解

    题目链接:https://www.luogu.org/problemnew/show/P1807 求最大路?就是把权值取相反数跑最短路. #include <cstdio> #includ ...

  8. 洛谷—— P1775 古代人的难题_NOI导刊2010提高(02)

    P1775 古代人的难题_NOI导刊2010提高(02) 题目描述 门打开了,里面果然是个很大的厅堂.但可惜厅堂内除了中央的一张羊皮纸和一支精致的石笔,周围几具骷髅外什么也没有.难道这就是王室的遗产? ...

  9. 洛谷P1771 方程的解_NOI导刊2010提高(01)

    题目描述 佳佳碰到了一个难题,请你来帮忙解决. 对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数), ...

随机推荐

  1. scrapy Crawl_spider

    命令行输入:scrapy genspider --list 可以看到scrapy给我们提供的爬虫模板: basiccrawlcsvfeedxmlfeed 一般都是用默认模板生成的spider,如果需要 ...

  2. WPF精修篇 多数据触发器

    原文:WPF精修篇 多数据触发器 有多属性触发器 就有多数据触发器 <Grid> <CheckBox x:Name="c1" Content="许可协议 ...

  3. 浅谈Vue.js2.0核心思想

    Vue.js是一个提供MVVM数据双向绑定的库,专注于UI层面,核心思想是:数据驱动.组件系统. 数据驱动: Vue.js数据观测原理在技术实现上,利用的是ES5Object.defineProper ...

  4. tcp 3次握手和4次挥手

    TCP标志位 (参考来源:https://blog.csdn.net/ltstud/article/details/73995933和 https://blog.csdn.net/weixin_308 ...

  5. ES6 Promise对象(七)

    一.Promise介绍1.Promise简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果2.Promise可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函 ...

  6. 记录vue项目 用hbuilder离线打包集成极光推送 安卓篇

    极光推送的官方demo: https://github.com/jpush/jpush-hbuilder-demo 里面也记录有详细的方法了. 我记录下自己的过程. 首先去极光那里创建一个应用 获取A ...

  7. Java 之 JDK1.8之前日期时间类

    一.JDK1.8之前日期时间类 二. java.lang.System类 System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1 ...

  8. 同步fifo与异步fifo

    参考以下帖子: https://blog.csdn.net/hengzo/article/details/49683707 https://blog.csdn.net/Times_poem/artic ...

  9. vue多个路由使用同一个页面,通过name判断参数,渲染页面数据

    项目中,发现有多个页面的数据内容相同,只是请求数据的参数不同,就可以使用同一个组件来渲染 这里的客户列表 / 我负责的 / 我参与的 都使用同一个组件,不同点在请求数据的参数 可以看到,通过钩子函数, ...

  10. 恭喜你!看到这6个MES系统选型的大坑,千万要避免!

    随着工业4.0概念的出现,智能化生产成为了各大制造业的发展趋势! MES系统可以为企业提供包括制造数据管理.计划排程管理.生产调度管理.库存管理.质量管理.人力资源管理.工作中心/设备管理.工具工装管 ...