1.Floyd
O
(
n
3
)
O(n^3)
O(n3)不用多说了。
2.
b
e
l
l
m
a
n
f
o
r
d
bellman_ford
bellmanford
你也可以叫他
S
P
F
A
SPFA
SPFA
具体来说(最优的方法)就是存每个点到他的最短路的路径长度,大于点数则有负环。
若求某点可达就直接按普通最短路
m
e
m
s
e
t
0
x
3
f
memset\ 0x3f
memset 0x3f然后从那个点开始拓展。
若求全局就从每个点都拓展一遍(也就是一开始全部压队列里),注意这时所有的
d
i
s
\rm dis
dis初始值都应该为0.
d
f
s
\rm dfs
dfs版本也不难理解但是会被卡成指数级,并且好像我随手写了一个BZOJ3232也没有
b
f
s
\rm bfs
bfs快?
模板
C
o
d
e
\rm Code
Code
#include<bits/stdc++.h>
#define maxn 2005
#define maxm 6005
using namespace std;
int n,m;
int info[maxn],Prev[maxm],to[maxm],cst[maxm],cnt_e;
void Node(int u,int v,int c){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cst[cnt_e]=c; }
int d[maxn],l[maxn],inq[maxn];
queue<int>q;
int main(){
int T;
for(scanf("%d",&T);T--;){
scanf("%d%d",&n,&m);
memset(info,0,sizeof info),cnt_e=0;
for(int i=1,a,b,w;i<=m;i++){
scanf("%d%d%d",&a,&b,&w);
Node(a,b,w);if(w>=0) Node(b,a,w);
}
memset(d,0x3f,sizeof d),memset(l,0,sizeof l),memset(inq,0,sizeof inq);
q.push(1);d[1]=0;
bool ERROR=0;
for(int u;!q.empty();){
u=q.front(),q.pop();
if(l[u]>=n){ ERROR=1;break; }
for(int i=info[u],v;i;i=Prev[i])
if(d[v=to[i]]>d[u]+cst[i]){
d[v]=d[u]+cst[i],l[v]=l[u]+1;
if(!inq[v]) inq[v]=1,q.push(v);
}
inq[u]=0;
}
for(;!q.empty();q.pop());
if(ERROR) puts("YE5");
else puts("N0");
}
}
B Z O J 3232 \rm BZOJ 3232 BZOJ3232分数规划找负环
C o d e : \rm Code: Code:
#include<bits/stdc++.h>
#define maxn 55
#define pii pair<int,int>
#define mp make_pair
#define eps 1e-4
using namespace std;
int n,m,s[maxn][maxn],sr[maxn][maxn],sc[maxn][maxn];
double d[maxn][maxn];int l[maxn][maxn],inq[maxn][maxn];
queue<pii>q;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&s[i][j]),s[i][j]+=s[i][j-1];
for(int i=0;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",&sr[i][j]);
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
scanf("%d",&sc[i][j]);
double L=0,R=1e3,mid;
for(int stp=0;stp<30;stp++){
mid=(L+R)*0.5;
for(;!q.empty();q.pop());
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
q.push(mp(i,j)),d[i][j]=l[i][j]=0,inq[i][j]=1;
bool flg = 0;
for(int u,v;!q.empty();){
u=q.front().first,v=q.front().second,q.pop();
if(l[u][v] > (n+1)*(m+1)){ flg=1; break;}
if(u && d[u-1][v]<d[u][v]-mid*sc[u][v]+s[u][v]){
d[u-1][v] = d[u][v]-mid*sc[u][v]+s[u][v] , l[u-1][v] = l[u][v] + 1;
if(!inq[u-1][v]) inq[u-1][v]=1,q.push(mp(u-1,v));
}
if(u<n && d[u+1][v]<d[u][v]-mid*sc[u+1][v]-s[u+1][v]){
d[u+1][v] = d[u][v]-mid*sc[u+1][v]-s[u+1][v] , l[u+1][v] = l[u][v]+1;
if(!inq[u+1][v]) inq[u+1][v]=1,q.push(mp(u+1,v));
}
if(v && d[u][v-1]<d[u][v]-mid*sr[u][v]){
d[u][v-1] = d[u][v]-mid*sr[u][v] , l[u][v-1] = l[u][v]+1;
if(!inq[u][v-1]) inq[u][v-1]=1,q.push(mp(u,v-1));
}
if(v<m && d[u][v+1]<d[u][v]-mid*sr[u][v+1]){
d[u][v+1] = d[u][v]-mid*sr[u][v+1],l[u][v+1] = l[u][v]+1;
if(!inq[u][v+1]) inq[u][v+1]=1,q.push(mp(u,v+1));
}
inq[u][v]=0;
}
if(flg) L=mid;else R=mid;
}
printf("%.3lf\n",L);
}