circle
circle
题目描述
小w 的男朋友送给小w 一个nn个点mm条边的图,并且***难小w 要她找出点数最少的正环。
小w 不会做,于是向你求助。
输入
第一行两个整数n,mn,m。
接下来mm行,每行四个数u,v,a,bu,v,a,b,表示从uu走到vv的代价为aa,从vv走到uu的代价为bb(算作两条不同的边)。注意a,ba,b可能为负。
输出
当图中包含正环时,输出点数最少的正环(简单环)的点数。
否则输出0。
样例输入
3 3
1 2 2 -1
2 3 10 -10
3 1 10 -10
样例输出
2
提示
对于前20%20%的数据,n≤7,m≤10
对于前60%60%的数据,n≤150,m≤2000
对于100%100%的数据,1≤n≤300,0≤m≤n(n−1)2,|a|,|b|≤104
数据保证不存在重边和自环。
来源
solution
原题似乎是cf 上的
令f[k][i][j]表示走2^k 步,i到j的最大距离
用就像floyd那样 矩阵倍增实现,条件为取max
如果2^k步是合法的,那么必有一个i满足f[k][i][i]>0
就像求lca那样按k从大到小往上跳
就是从大到小枚举k 如果f[k]*ans不合法,那就乘进答案
这样找到最小的步数
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 305
#define inf 1e9
using namespace std;
int n,m,t1,t2,v1,v2;
struct node{
int v[maxn][maxn];
}f[9];
node ch(node a,node b){
node c;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
c.v[i][j]=-inf;
for(int k=1;k<=n;k++){
c.v[i][j]=max(c.v[i][j],a.v[i][k]+b.v[k][j]);
}
}
return c;
}
int main()
{
cin>>n>>m;
for(int k=0;k<=8;k++)
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)f[k].v[i][j]=f[k].v[j][i]=-inf;
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&t1,&t2,&v1,&v2);
f[0].v[t1][t2]=max(f[0].v[t1][t2],v1);
f[0].v[t2][t1]=max(f[0].v[t2][t1],v2);
}
for(int i=1;i<=8;i++)f[i]=ch(f[i-1],f[i-1]);
node ans,now;int bs=0,flag=0;
for(int i=8;i>=0;i--){
if(flag)now=ch(ans,f[i]);
else now=f[i];
bool fl=0;
for(int a=1;a<=n;a++){
if(now.v[a][a]>0)fl=1;
}
if(!fl){bs+=(1<<i);ans=now;flag=1;}
}
if(bs+1==512)puts("0");
else cout<<bs+1<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构