各種模板 - 持續更新中···

無限長大數(理論)

class BigInt
{
public:
	BigInt():num(), negative(false){}
	BigInt(const LLT);
	BigInt(const char*);
	BigInt(const string);
	BigInt(const BigInt & x);
	BigInt & operator = (const BigInt &);
	friend istream & operator >> (istream &, BigInt &);
	friend ostream & operator << (ostream &, BigInt);
	const BigInt operator + (const BigInt &) const;
	const BigInt operator - (const BigInt &) const;
	const BigInt operator * (const BigInt &) const;
	const BigInt operator / (const LLT &) const;
	const LLT operator % (const LLT &) const;
	bool operator > (const BigInt &) const;
	bool operator < (const BigInt &) const;
	bool operator == (const BigInt &) const;
	bool operator >= (const BigInt &) const;
	bool operator <= (const BigInt &) const;
	friend const BigInt abs(const BigInt &);
	const BigInt operator - () const;
private:
	deque<int> num;
	bool negative;
};

BigInt::BigInt(const LLT x){
	LLT t = abs(x);
	negative = x >= 0 ? false : true;
	while (t > 0){
		num.push_back(t % 10);
		t /= 10;
	}
}
BigInt::BigInt(const char* str){
	unsigned i = str[0] == '-' ? 1 : 0;
	this->negative = (str[0] == '-' ? true : false);
	for (; i < strlen(str); ++i) num.push_back(str[i] - '0');
}
BigInt::BigInt(const string str){
	unsigned i = str[0] == '-' ? 1 : 0;
	this->negative = (str[0] == '-' ? true : false);
	for (; i < str.size(); ++i) num.push_back(str[i] - '0');
}
BigInt::BigInt(const BigInt &x):num(x.num), negative(x.negative){}
BigInt & BigInt::operator = (const BigInt &x){
	negative = x.negative;
	num = x.num;
	return (*this);
}
istream & operator >> (istream &is, BigInt & x){
	string str; is >> str;
	x = str;
	return is;
}
ostream & operator << (ostream &os, BigInt x){
	if (x.negative) os << '-';
	for (unsigned i = 0; i != x.num.size(); ++i)
		os << x.num[i];
	return os;
}
bool BigInt::operator > (const BigInt & rhs) const {
	BigInt x = (*this), y = rhs;
	if (!x.negative && y.negative) return true;
	if (x.negative && !y.negative) return false;
	if (x.negative && y.negative) swap(x, y);
	if (x.num.size() > y.num.size()) return true;
	if (x.num.size() < y.num.size()) return false;
	for (unsigned i = 0; i != x.num.size(); ++i) {
		if (x.num[i] > y.num[i]) return true;
		if (x.num[i] < y.num[i]) return false;
	}
	return false;
}
bool BigInt::operator < (const BigInt & rhs) const {
    return rhs < *this;
}
bool BigInt::operator == (const BigInt & rhs) const {
	return negative == rhs.negative && num == rhs.num;
}
bool BigInt::operator >= (const BigInt & rhs) const {
	return *this > rhs || *this == rhs;
}
bool BigInt::operator <= (const BigInt & rhs) const {
    return rhs >= *this;
}
const BigInt abs(const BigInt & rhs){
	BigInt res;
	res.negative = false;
	res.num = rhs.num;
	return res;
}
const BigInt BigInt::operator - () const {
	BigInt ret = *this; ret.negative = !ret.negative;
	return ret;
}
const BigInt BigInt::operator + (const BigInt & y) const {
	if (!this->negative && y.negative) return *this - abs(y);
	if (this->negative && !y.negative) return y - abs(*this);
	if (this->negative && y.negative) return -(abs(*this) + abs(y));
	BigInt x = *this, res;
	int temp = 0;
	for (int i = x.num.size() - 1, j = y.num.size() - 1; i >= 0 || j >= 0; --i, --j) {
		int a = i < 0 ? 0 : x.num[i];
		int b = j < 0 ? 0 : y.num[j];
		res.num.push_front((a + b + temp) % 10);
		temp = (a + b + temp) / 10;
	}
	if (temp != 0) res.num.push_front(temp);
	return res;
}
const BigInt BigInt::operator * (const BigInt & y) const {
	deque<int> a, b, res;
	copy(this->num.begin(), this->num.end(), front_inserter(a));
	copy(y.num.begin(), y.num.end(), front_inserter(b));
	res.resize(a.size() + b.size() + 5);
	for (unsigned i = 0; i < a.size(); ++i) for (unsigned j = 0; j < b.size(); ++j)
		res[i + j] += a[i] * b[j];
	for (unsigned i = 0; i < res.size() - 1; ++i){
		res[i + 1] += res[i] / 10;
		res[i] %= 10;
	}
	while (res.size() >= 2 && res.back() == 0)
		res.pop_back();
	reverse(res.begin(), res.end());
	BigInt ret; ret.negative = this->negative ^ y.negative; ret.num = res;
	return ret;
}
const BigInt BigInt::operator - (const BigInt & y) const {
	if (!this->negative && y.negative) return *this + abs(y);
	if (this->negative && !y.negative) return -(abs(*this) + y);
	if (this->negative && y.negative) return abs(y) - abs(*this);
	deque<int> a, b, res; BigInt ret;
	copy(this->num.begin(), this->num.end(), front_inserter(a));
	copy(y.num.begin(), y.num.end(), front_inserter(b));
	if (y > *this) swap(a, b), ret.negative = true;
	res.resize(max(a.size(), b.size()) + 5);
	for (unsigned i = 0, j = 0; i < a.size() || j < b.size(); ++i, ++j){
		int m = i < a.size() ? a[i] : 0;
		int n = j < b.size() ? b[j] : 0;
		res[i] = m - n;
	}
	for (unsigned i = 0; i < res.size() - 1; ++i) if (res[i] < 0) {
		res[i] += 10;
		--res[i + 1];
	}
	while (res.size() >= 2 && res.back() == 0)
		res.pop_back();
	reverse(res.begin(), res.end()); ret.num = res;
	return ret;
}
const BigInt BigInt::operator / (const LLT & rhs) const {
	LLT temp = 0;
	BigInt x = (*this), res;
	res.negative = this->negative ^ (rhs < 0 ? 1 : 0);
	int y = abs(rhs);
	for (unsigned i = 0; i < x.num.size(); ++i){
		temp = temp * 10 + x.num[i];
		res.num.push_back((int)(temp / y));
		temp %= y;
	}
	while (res.num.size() >= 2 && res.num.front() == 0)
		res.num.pop_front();
	return res;
}
const LLT BigInt::operator % (const LLT & y) const {
	LLT res = 0;
	for (unsigned i = 0; i < this->num.size(); ++i)
		res = (res * 10 + this->num[i]) % y;
	return res;
}

LCA


//求樹上兩點之間的距離
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+233;
int pre[N][30],deep[N],n;
int vis[N];
vector<int > e[N];
void bfs(int x){
	queue<int > que;
	que.push(x);
	vis[x] = 1;
	deep[x] = 1;
	while(!que.empty()){
		x = que.front(); que.pop();
		// printf("x:%d ", x);
		// printf("deep[%d]:%d\n",x,deep[x] );
		int size = e[x].size();
		for(int i=0;i<size;++i){
			int u = e[x][i];
			if(!vis[u]){
				vis[u] = 1;
				que.push(u);
				pre[u][0] = x;
				deep[u] = deep[x] + 1;
			}
		}
	}
}
void getpre(){
	for(int j=1;(1<<j)<=n;j++){
        for(int i=1;i<=n;i++){
        	if(pre[i][j-1] != -1)
        		pre[i][j]=pre[pre[i][j-1]][j-1];
        }
    }
}
int lca(int a,int b)
{
    int i,j;
    if(deep[a]<deep[b])swap(a,b);
    for(i=0;(1<<i)<=deep[a];i++);
    i--;
    for(j=i;j>=0;j--)
        if(deep[a]-(1<<j)>=deep[b])
            a=pre[a][j];
    if(a==b)return a;
    for(j=i;j>=0;j--)
    {
        if(pre[a][j]!=-1&&pre[a][j]!=pre[b][j])
        {
            a=pre[a][j];
            b=pre[b][j];
        }
    }
    return pre[a][0];
}

int main(){
	scanf("%d", &n);
	int u, v;
	memset(pre, -1, sizeof pre);
	for(int i=1; i<n; ++i){
		scanf("%d %d", &u,&v);
		e[u].push_back(v);
		e[v].push_back(u);
	}
	bfs(1);
	// for(int i=1; i<=n; ++i)	printf("%d\n", deep[i]);
	getpre();
	// for(int i=1; i<=n; ++i)	printf("%d\n", pre[i][0]);
	ll ans = 0;
	for(int i=1; i<=n; ++i){
		for(int j=i; j<=n; j+=i){
			ans += (deep[i]+deep[j]-2*deep[lca(i,j)]+1);
		}
	}
	printf("%lld\n", ans-n);
	return 0;
}

逆元打表

inv[i] = (p-p/i)*inv[p%i]%p;

SG函數打表

int op[110],sg[11000];
int k,N;
vector<int > s;
void getSG(){
    sg[0] = 0;
    for(int i=1;i<=N;++i){
        s.clear();
        for(int j=1;i>=op[j] && j<=k;++j)
            s.push_back(sg[i - op[j]]);
        for(int j=0;;++j){
            if(count(s.begin(),s.end(),j) == 0){
                sg[i] = j;
                break;
            }
        }
    }
}

線性素數+莫比烏斯函數打表

int miu[MAXN+10], check[MAXN+10], prime[MAXN+10];
void Mobius()
{
    memset(check,false,sizeof(check));
    miu[1] = 1;
    int tot = 0;
    for(int i = 2; i <= MAXN; i++)
    {
        if( !check[i] )
        {
            prime[tot++] = i;
            miu[i] = -1;
        }
        for(int j = 0; j < tot; j++)
        {
            if(i * prime[j] > MAXN) break;
            check[i * prime[j]] = true;
            if( i % prime[j] == 0)
            {
                miu[i * prime[j]] = 0;
                break;
            }
            else
            {
                miu[i * prime[j]] = -miu[i];
            }
        }
    }	
}

BM(秒殺線性遞推):

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cassert>
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// head

int _,n;
namespace linear_seq {
    const int N=10010;
    ll res[N],base[N],_c[N],_md[N];

    vector<int> Md;
    void mul(ll *a,ll *b,int k) {
        rep(i,0,k+k) _c[i]=0;
        rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
        for (int i=k+k-1;i>=k;i--) if (_c[i])
            rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
        rep(i,0,k) a[i]=_c[i];
    }
    int solve(ll n,VI a,VI b) { // a 係數 b 初值 b[n+1]=a[0]*b[n]+...
//        printf("%d\n",SZ(b));
        ll ans=0,pnt=0;
        int k=SZ(a);
        assert(SZ(a)==SZ(b));
        rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
        Md.clear();
        rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
        rep(i,0,k) res[i]=base[i]=0;
        res[0]=1;
        while ((1ll<<pnt)<=n) pnt++;
        for (int p=pnt;p>=0;p--) {
            mul(res,res,k);
            if ((n>>p)&1) {
                for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
                rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
            }
        }
        rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
        if (ans<0) ans+=mod;
        return ans;
    }
    VI BM(VI s) {
        VI C(1,1),B(1,1);
        int L=0,m=1,b=1;
        rep(n,0,SZ(s)) {
            ll d=0;
            rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
            if (d==0) ++m;
            else if (2*L<=n) {
                VI T=C;
                ll c=mod-d*powmod(b,mod-2)%mod;
                while (SZ(C)<SZ(B)+m) C.pb(0);
                rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
                L=n+1-L; B=T; b=d; m=1;
            } else {
                ll c=mod-d*powmod(b,mod-2)%mod;
                while (SZ(C)<SZ(B)+m) C.pb(0);
                rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
                ++m;
            }
        }
        return C;
    }
    int gao(VI a,ll n) {
        VI c=BM(a);
        c.erase(c.begin());
        rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
        return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
    }
};

int main() {
/*手推或者寫程序跑出來前幾項,一般10項就夠了*/
	vector<int>v;
    v.push_back(3);
    v.push_back(9);
    v.push_back(20);
    v.push_back(46);
    v.push_back(106);
    v.push_back(244);
    v.push_back(560);
    v.push_back(1286);
    v.push_back(2956);
    v.push_back(6794);
    v.push_back(15610);
    v.push_back(35866);
    v.push_back(82416);
    v.push_back(189384);
    v.push_back(435170);
    v.push_back(999936);
	int T;
	cin >> T;
	ll n;
    while (T--) {
        cin >> n;
        printf("%d\n",linear_seq::gao(v,n-1));
    }
}


矩陣快速冪:

/*這是一個求Fn = a*Fn-1 + b*Fn-2 的斐波那契遞推的板子*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 7;
struct Matrix
{
    ll m[5][5];
};

Matrix Mul(Matrix a,Matrix b){
    Matrix res;
    int n=2;
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            res.m[i][j] = 0;
        }
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=n;++j){
            for(int k=1;k<=n;++k){
                res.m[i][j] = (res.m[i][j]%mod+a.m[i][k]*b.m[k][j]%mod)%mod;
                // printf("%d\n",res.m[i][j] );
            }
        }
    }
    return res;
}

void MatrixQuickPower(int n,int a,int b){
    Matrix Mat,res;
    Mat.m[1][1] = a;res.m[1][1] = 1;
    Mat.m[1][2] = b;res.m[1][2] = 0;
    Mat.m[2][1] = 1;res.m[2][1] = 0;
    Mat.m[2][2] = 0;res.m[2][2] = 1;
    while(n){
        if(n&1) res = Mul(res,Mat);
        n >>= 1;
        Mat = Mul(Mat,Mat);
    }
    printf("%lld\n", (res.m[1][1]+res.m[1][2]+mod*mod)%mod);//注意有負數的情況
}
int main(int argc, char const *argv[])
{
    int a,b,n;
    while(cin>>a>>b>>n){
        if(n == 1 || n == 2)    puts("1");
        else MatrixQuickPower(n-2,a,b);
    }
    return 0;
}

Lucas定理求C(n,m)% P:

typedef long long LL;

LL mod;

inline LL pow(LL a, LL b)//快速冪是爲了求逆元
{
    LL ans = 1;
    for(; b; b >>= 1,a = a * a % mod)
        if(b & 1)
            ans = ans * a % mod;
    return ans;
}

LL farc[1000005];

inline void prepare(LL a)
{
    farc[0]=1;
    for(LL i = 1; i <= a; ++i)
        farc[i]=farc[i-1]*i%mod;
}

inline LL Csmall(LL m, LL n) // C(m,n) = (n!)/(m!*(n-m)!)
{
    if(n < m)
        return 0;
    return farc[n] * pow(farc[m], mod-2) % mod * pow(farc[n-m], mod-2) % mod; // 費馬小定理求逆元
}

inline LL C(LL m, LL n)
{
    if(n < m)
        return 0;
    if(!n)
        return 1;//Lucas的邊界條件
    return C(m/mod, n/mod) % mod * Csmall(m%mod, n%mod) % mod; // 上面證明的Lucas定理
}

GCD:

LL gcd(LL a,LL b){
    while(b^=a^=b^=a%=b);
    return a;
}

Ex-GCD:

int Ex_Gcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int r = exGcd(b,a%b,x,y);
    t = x; x = y;
    y = t-a/b*y;
    return r;
}

Ex_GCD求逆元:

void extgcd(ll a,ll b,ll& d,ll& x,ll& y){
    if(!b){ d=a; x=1; y=0;}
    else{ extgcd(b,a%b,d,y,x); y-=x*(a/b); }
}
ll inverse(ll a,ll n){
    ll d,x,y;
    extgcd(a,n,d,x,y);
    return d==1?(x+n)%n:-1;
}

快速冪:

ll pow_mod(ll x, ll n, ll mod){
    ll res=1;
    while(n>0){
        if(n&1)res=res*x%mod;
        x=x*x%mod;
        n>>=1;
    }
    return res;
}

根據費馬小定理,可用快速冪求逆元。

歐拉篩(線性):

int Mark[MAXN];  
int prime[MAXN];  

int Prime(){  
    int tot = 0;  
    memset(Mark, 0, sizeof(Mark));  
    Mark[0] = 1; Mark[1] = 1;
    for(int i = 2; i < MAXN; i++)  
    {  
        if(Mark[i] == 0){  
            prime[tot++] = i;  
        }  
        for(int j = 0; j < tot && prime[j] * i < MAXN; j++)  
        {  
            Mark[i * prime[j]] = 1;  
            if(i % prime[j] == 0){  
                break;  
            }  
        }  
    }  
    return tot;  
} 

大於等於5的質數一定和6的倍數相鄰(適合訪問量較小時):

bool isprime(ll n){
    if(n == 1)  return 0;
    if(n == 2 || n == 3)    return 1;
    if(n%6 != 5 && n%6 != 1)    return 0;
    for(ll i=5 ; i*i <= n; i += 6){
        if(n%i == 0 || n%(i+2) == 0)    return 0;
    }
    return 1;
}

KMP求兩字符串是否匹配:

const int maxn = 2e6+100;
int n,m;
char s[maxn];
char t[maxn];
int next[maxn];
void getnext(){
	int i=0,j=-1;
	next[0] = -1;
	while(i<m){
		if(j == -1 || t[i] == t[j])
			next[++i] = ++j;
		else	j = next[j];
	}
	// for(int i=1;i<=m;++i)	printf("%d ", next[i]);
	// puts("");
}
bool kmp(){
    getnext();
    int i=0,j=0;
    while(i<n){
        if(j == -1 || s[i] == t[j]){
            i++;j++;
        }
        else j = next[j];
        if(j == m)    return 1;
    }
    return 0;
}

Manacher求最長迴文字串:

const int N = 3e6;
char s[N];
char s_new[N];
int p[N];

int Init()
{
    int len = strlen(s);
    s_new[0] = '$';
    s_new[1] = '#';
    int j = 2;

    for (int i = 0; i < len; i++)
    {
        s_new[j++] = s[i];
        s_new[j++] = '#';
    }

    s_new[j] = '\0';  // 別忘了哦
    
    return j;  // 返回 s_new 的長度
}

int Manacher()
{
    int len = Init();  // 取得新字符串長度並完成向 s_new 的轉換
    int max_len = -1;  // 最長迴文長度

    int id;
    int mx = 0;

    for (int i = 1; i < len; i++)
    {
        if (i < mx)
            p[i] = min(p[2 * id - i], mx - i);  // 需搞清楚上面那張圖含義, mx 和 2*id-i 的含義
        else
            p[i] = 1;

        while (s_new[i - p[i]] == s_new[i + p[i]])  // 不需邊界判斷,因爲左有'$',右有'\0'
            p[i]++;

        // 我們每走一步 i,都要和 mx 比較,我們希望 mx 儘可能的遠,這樣才能更有機會執行 if (i < mx)這句代碼,從而提高效率
        if (mx < i + p[i])
        {
            id = i;
            mx = i + p[i];
        }

        max_len = max(max_len, p[i] - 1);
    }

    return max_len;
}

SPFA求最短路:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int ,int> pii;
const int INF = 0x3f3f3f3f;
const int N = 3e3+10;
const int M = 7e3+10;

struct EDGE{
	int next;
	int to;
	int w;
}edge[M];

int head[N],dis[N];
bool inq[N];
int T,C,Ts,Te,cnt = 0;

void add(int u, int v, int w){
	edge[++cnt].next = head[u];
	edge[cnt].to = v;
	edge[cnt].w  = w;
	head[u] = cnt;
}

void SPFA(){
	memset(dis, INF, sizeof dis);
	dis[Ts] = 0;
	int p; queue<int > que;	
	que.push(Ts); inq[Ts] = true;
	while(!que.empty()){
		p = que.front();que.pop();inq[p] = false;
		for(int i = head[p]; ~i; i = edge[i].next){
			int u = edge[i].to;
			if(dis[u] > dis[p] + edge[i].w){
				dis[u] = dis[p] + edge[i].w;
				if(!inq[u]){
					inq[u] = true;
					que.push(u);
				}
			}
		}
	}
	printf("%d\n", dis[Te]);
}
int main(int argc, char const *argv[])
{
	memset(head, -1, sizeof head);
	cnt = 0;
	int u, v, w;
	scanf("%d %d %d %d",&T, &C, &Ts, &Te);
	for(int i=1;i<=C;++i){
		scanf("%d %d %d",&u, &v, &w);
		add(u, v, w);
		add(v, u, w);
	}
	SPFA();
	return 0;
}
/*
7 11 5 4
2 4 2
1 4 3
7 2 2
3 4 3
5 7 5
7 3 3
6 1 1
6 3 4
2 4 3
5 6 3
7 2 1

7
*/

堆優化Dijstra:

const int INF = 0x3f3f3f3f;
const int N = 5e6+10;
const int M = 5e6+10;

struct EDGE{
    int next;
    int to;
    int w;
}edge[M];

int n,m,k,s,e,cnt = 1;
int head[N],dis[N];
bool inq[N];  //是否訪問過

void add(int u, int v, int w){
    edge[cnt].next = head[u];
    edge[cnt].to = v;
    edge[cnt].w  = w;
    head[u] = cnt++;
}

struct NODE{
    int id,dist;
}q,p;
bool operator < (NODE a, NODE b){
    return a.dist > b.dist;
}
void Dijkstra(){
    memset(dis, INF, sizeof dis);
    memset(inq, 0, sizeof inq);
    priority_queue<NODE> que;
    p.id = s; p.dist = 0; 
    dis[s] = 0; que.push(p); 
    while(!que.empty()){
        q = que.top(); que.pop();
        if(inq[q.id])   continue;
        inq[q.id] = true;
        for(int i=head[q.id]; ~i; i=edge[i].next){
            int u = edge[i].to;
            if(dis[u] > q.dist + edge[i].w){
                dis[u] = q.dist + edge[i].w;
                p.id = u;
                p.dist = dis[u];
                que.push(p);
            }
        }
    }
}

最大流EK:

const int N = 210;
int n, m, c[N][N], pre[N], mmin;

bool bfs(int s, int t){
	memset(pre, -1, sizeof pre);
	pre[s] = 0;
	queue<int> que;
	mmin = INF;
	que.push(s);
	while(!que.empty()){
		int x = que.front(); que.pop();
		for(int i = 1; i <= m; ++i){
			if(c[x][i] > 0 && pre[i] == -1){
				pre[i] = x;
				mmin = min(mmin, c[x][i]);
				if(i == t)	return true;
				que.push(i);
			}
		}
	}
	if(pre[t] != -1)	return true;
	else return false;
}
void EdmondsKarp(int s, int t){
	int sum = 0;
	while(bfs(s,t)){
		sum += mmin;
		int x = t;
		while(x){
			c[pre[x]][x] -= mmin;
			c[x][pre[x]] += mmin;
			x = pre[x];
		}
	}
	printf("%d\n", sum);
}

最大流Dinic:

const int INF = 0x3f3f3f3f;
const int MAXN = 1e5;
const int MAXM = 3e5;

struct Edge{
    int next;
    int u, v, w;
};
int n, m, s, t;
int cnt, head[MAXN];
int dis[MAXN], cur[MAXN];
Edge edge[MAXM];
queue<int> que;

void init(){
    cnt = 0;
    memset(cur, 0, sizeof cur);
    memset(head, -1, sizeof head);
}
void add(int u, int v, int w){
    edge[cnt].u = u; edge[cnt].v = v;
    edge[cnt].w = w; edge[cnt].next = head[u];
    head[u] = cnt++;
    edge[cnt].u = v; edge[cnt].v = u;
    edge[cnt].w = 0; edge[cnt].next = head[v];
    head[v] = cnt++;
}

int bfs(){
    while(!que.empty()) que.pop();
    memset(dis, -1, sizeof dis);
    que.push(s); dis[s] = 0;
    while(!que.empty()){
        int x = que.front(); que.pop();
        if(x == t)	return 1;
        for(int i=head[x]; ~i; i=edge[i].next){
            int& v = edge[i].v, w = edge[i].w;
            if(dis[v] == -1 && w > 0){
                dis[v] = dis[x] + 1;
                que.push(v);
            }
        }
    }
    return 0;
}

int dfs(int x, int maxflow){
    if(x == t || !maxflow)	return maxflow;
    int flow = 0;
    for(int i=head[x]; ~i; i=edge[i].next){
        int& v = edge[i].v, w = edge[i].w;
        if(dis[x] + 1 == dis[v] && w > 0){
            int delta = dfs(v, min(maxflow-flow, w));
            if(delta > 0){
                edge[i].w -= delta;
                edge[i^1].w += delta;
                flow += delta;
                maxflow -= delta;
                if(!maxflow)	break;
            }
        }
    }
    return flow;
}

int dinic(){
    int ans = 0;
    while(bfs()){
        ans += dfs(s, INF);
    }
    return ans;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章