在忘记考虑负环之后,黎瑟的算法又出错了。对于边带权的有向图 G = (V, E),请找出一个点数最小的环,使得
环上的边权和为负数。保证图中不包含重边和自环。
标签:tmp namespace mat eof include min des ret space
BZOJ_4773_负环
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 350 int f[N][N][20],n,m,L[N]; struct Mat { int v[301][301]; Mat(){memset(v,0x3f,sizeof(v));} Mat operator*(const Mat &x)const { Mat re;int i,j,k; for(k=1;k<=n;k++) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { re.v[i][j]=min(re.v[i][j],v[i][k]+x.v[k][j]); } } } return re; } }dis[10]; bool judge(Mat x) { int i; for(i=1;i<=n;i++) { if(x.v[i][i]<0) return 1; } return 0; } int main() { scanf("%d%d",&n,&m); int i,x,y,z,sum=0; Mat tmp; for(i=1;i<=n;i++) dis[0].v[i][i]=tmp.v[i][i]=0; for(i=2;i<=n;i++) L[i]=L[i>>1]+1; for(i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); dis[0].v[x][y]=z; } for(i=1;i<=L[n];i++) dis[i]=dis[i-1]*dis[i-1]; for(i=L[n];i>=0;i--) { if(!judge(tmp*dis[i])) { tmp=tmp*dis[i]; sum+=(1<<i); } } tmp=tmp*dis[0]; printf("%d\n",judge(tmp)?sum+1:0); }
标签:tmp namespace mat eof include min des ret space
原文地址:https://www.cnblogs.com/suika/p/8893205.html