洛谷 P1807 最长路_NOI导刊2010提高(07)题解
相当与一个拓扑排序的模板题吧
蒟蒻的辛酸史

题目大意:给你一个有向无环图,让你求出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)题解的更多相关文章
- 洛谷 P1807 最长路_NOI导刊2010提高(07) 题解
P1807 最长路_NOI导刊2010提高(07) 题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算 ...
- 洛谷 P1807 最长路_NOI导刊2010提高(07)
最长路 #include <iostream> #include <cstdio> #include <cstring> #include <queue> ...
- 洛谷P1807 最长路_NOI导刊2010提高(07)
//拓扑排序求最长路 #include<bits/stdc++.h> #include<queue> using namespace std; const int INF=0x ...
- 图论--最长路--洛谷P1807 最长路_NOI导刊2010提高(07)
题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入格式 ...
- luogu P1807 最长路_NOI导刊2010提高(07)
题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入格式 ...
- P1807 最长路_NOI导刊2010提高(07)
题目描述 设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j.设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径. 输入输出 ...
- 【luogu P1807 最长路_NOI导刊2010提高(07)】 题解
题目链接:https://www.luogu.org/problemnew/show/P1807 求最大路?就是把权值取相反数跑最短路. #include <cstdio> #includ ...
- 洛谷—— P1775 古代人的难题_NOI导刊2010提高(02)
P1775 古代人的难题_NOI导刊2010提高(02) 题目描述 门打开了,里面果然是个很大的厅堂.但可惜厅堂内除了中央的一张羊皮纸和一支精致的石笔,周围几具骷髅外什么也没有.难道这就是王室的遗产? ...
- 洛谷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的余数), ...
随机推荐
- mvn手动上传jar到本地仓库
mvn install:install-file -Dfile=G:\elastic-project\workspace\out\artifacts\xxl_job_core_jar\xxl-job- ...
- 明解C语言 入门篇 第十章答案
练习10-1 #include <stdio.h> void adjust_point(int*n) { ) *n = ; ) *n = 0; } int main() { int x; ...
- Security实现登录安全控制
1:在pom.xml中添加依赖 <!-- 身份验证 --> <dependency> <groupId>org.springframework.security&l ...
- Intellij IDEA的安装教程
一.下载安装 1.打开官网:http://www.jetbrains.com/idea/,点击页面中的“DOWNLOAD” 2.根据自己的需要选择下载的IntelliJ IDEA版本,此处我的电脑是W ...
- Linux 安装Redis4.0.8【yum安装】
.下载yum源 yum install epel-release2.安装redisyum install redis3.启动redis # 启动redis service redis start # ...
- 执行"rm -rf /"之后世界安静了吗
对于Unix/Linux程序员来说,"rm -rf /"一直被认为是一个极度危险的操作,因为直接把根目录给删除了,整个操作系统也就崩溃了.但实际上会是这样的吗?呵呵,请看图: 啊哈 ...
- SSM基本配置详解
需要查看SSM基本依赖和完整配置文件的到:SSM基本配置及依赖 示例项目:SSMDemo 1 Spring IOC容器配置 1.1 applicationContext.xml 1.1.1 配置数据源 ...
- R数据挖掘 第一篇:聚类分析(划分)
聚类是把一个数据集划分成多个子集的过程,每一个子集称作一个簇(Cluster),聚类使得簇内的对象具有很高的相似性,但与其他簇中的对象很不相似,由聚类分析产生的簇的集合称作一个聚类.在相同的数据集上, ...
- 【java】查看Java字节码文件内容的方法+使用javap找不到类 解决方法
研究synchronized底层实现,涉及到查看java字节码的需要 前提是,你的PC已经成功安装了JDK并别配置了环境变量. ==========查看方法========= 一.javap查看简约字 ...
- 2019-11-29-WPF-高性能笔
原文:2019-11-29-WPF-高性能笔 title author date CreateTime categories WPF 高性能笔 lindexi 2019-11-29 10:20:51 ...