标签:cnt NOI vis int 题解 head tot P1807 dis
思路:SPFA加判负环,因为边权加边的时候变负,最后答案再取负。
不多说,上代码:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N = 500005;
const int INF = 2147483647;
struct Edge {
int next, to, w;
}e[N];
int n,m,x,y,w,head[N],vis[N],dis[N],cnt[N],tot;
queue < int > q;
void spfa()
{
vis[1] = 1;//标记入队
dis[1] = 0;
cnt[1] = 1;//cnt是记录第几步
q.push(1);
while (!q.empty()) {
int u = q.front();
q.pop();
vis[u] = 0;//出队
for (int i=head[u]; i!=-1; i=e[i].next) {
int v = e[i].to;
if (dis[u] + e[i].w < dis[v])
{
cnt[v] = cnt[u] +1;//步数加1
if (cnt[v] > n) return;//如果一条边的步数超过了点的个数便已经是负环了,没必要再继续找
dis[v] = dis[u] + e[i].w;//更新
if (vis[v] == 0)//入队
{
q.push(v);
vis[v] = 1;
}
}
}
}
}
void add(int from, int to, int W) {//邻接表加边
tot ++;
e[tot].to = to;
e[tot].w = W;
e[tot].next = head[from];
head[from] = tot;
}
int main()
{
memset(head, -1, sizeof(head));//初始化
scanf("%d %d", &n, &m);
for (int i=1; i<=n; i++) {//初始化
vis[i] = 0;
dis[i] = INF;
}
for (int i=1; i<=m; i++) {
scanf("%d %d %d", &x, &y, &w);
add(x, y, -w);//权值取负
}
spfa();
if (dis[n] == INF) printf("-1"); else//值不变即不连通
printf("%d", -dis[n]);//否则输出取负的答案
return 0;
}
标签:cnt,NOI,vis,int,题解,head,tot,P1807,dis 来源: https://www.cnblogs.com/N-S-P/p/12498902.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。