神奇的小本本
1.SPFA判负环:
(1)BFS:
可以在每一个点入对的时候进行计数器计数的操作
如果计数器计的数大于n那就是存在负环
(队列)
代码
bool SPFA(int s)
{
int x,y,i,j; queue<int>q;
memset(d,127,sizeof(d)); memset(vis,false,sizeof(vis));
while(!q.empty()) q.pop();
d[s]=0;
cnt[s]=1;
q.push(s);
vis[s]=true;
while(!q.empty())
{
x=q.front();
q.pop();
vis[x]=false;
for(i=first[x];i;i=next[i])
{
y=v[i];
if(d[y]>d[x]+w[i])
{
d[y]=d[x]+w[i];
cnt[y]=cnt[x]+1;
if(cnt[y]>n)
return false;
if(!vis[y])
{
q.push(y);
vis[y]=true;
}
}
}
}
return true;
}
(2)DFS
如果这一个点送驰过的点之后在松弛的点再能够回来松弛这个点那就说明有负环
(有栈的意思)
//看代码中的注释
代码:
void spfa(int x)
{
int i,j;
vis[x]=true;
for(i=first[x];i;i=next[i])
{
j=v[i];
if(d[j]>d[x]+w[i])
{//因为这个地方j如果是在x之前的那d[x]一定大于d[j]但是这里突然出现d[j]大于的d[x]加上了一个数那么这个数一定是负的
//这里求的不是负边而是负环所以这个负数特别小时不会影响的
if(vis[j])
{
flag=false;
return;
}
d[j]=d[x]+w[i];
spfa(j);
}
}
vis[x]=false;
}
2.快速幂模板
#include<iostream>
#include<cstdio>
using namespace std;
long long b,p,k;
long long a,c,ans = 1;
int main()
{
cin>>b>>p>>k;
a = p,c = b;
while(a > 0)
{
if(a & 1 == 1)
{
ans *= c;
ans %= k;
}
a /= 2;
c = (c % k) * (c % k) % k;
}
printf("%lld^%lld mod %lld=%lld\n",b,p,k,ans % k);
return 0;
}
3.图论小细节
(1)自环是什么?
自环就是从自己到自己有一条路这种情况一般是不会出现的,出现的时候题目中一般会说出,一般是要特判一下避免这种情况出现
4.如何求一个数的乘法逆元
由费马小定理 \(a^{(p - 1)}\equiv1\pmod{p}\) ( \(p\) 为素数),稍作变形即是 \(aa^{p - 2}\equiv1\pmod{p}\) ,发现了 \(a^{p - 2}\) 即是 \(a\) 的逆元,可以用快速幂来辅助求(详见知识点2)