zoukankan      html  css  js  c++  java
  • 板子们。。。。

    沙雕的gcd:

    //1.gcd
    int gcd(int a,int b) {
        return b?gcd(b,a%b):a;
    }
    View Code

    还有个exgcd:

    //2.扩展gcd )extend great common divisor
    ll exgcd(ll l,ll r,ll &x,ll &y) {
        if(r==0) {
            x=1;
            y=0;
            return l;
        } else {
            ll d=exgcd(r,l%r,y,x);
            y-=l/r*x;
            return d;
        }
    }
    View Code

    求逆元:

    //3.求a关于m的乘法逆元
    ll mod_inverse(ll a,ll m) {
        ll x,y;
        if(exgcd(a,m,x,y)==1)//ax+my=1
            return (x%m+m)%m;
        return -1;//不存在
    }

    快速幂:

    //4.快速幂quick power
    ll qpow(ll a,ll b,ll m) {
        ll ans=1;
        ll k=a;
        while(b) {
            if(b&1)ans=ans*k%m;
            k=k*k%m;
            b>>=1;
        }
        return ans;
    }

    快速乘(也叫二分乘法):

    //5.快速乘,直接乘会爆ll时需要它,也叫二分乘法。
    ll qmul(ll a,ll b,ll m) {
        ll ans=0;
        ll k=a;
        ll f=1;//f是用来存负号的
        if(k<0) {
            f=-1;
            k=-k;
        }
        if(b<0) {
            f*=-1;
            b=-b;
        }
        while(b) {
            if(b&1)
                ans=(ans+k)%m;
            k=(k+k)%m;
            b>>=1;
        }
        return ans*f;
    }

    中国剩余定理:

    //6.中国剩余定理CRT (x=ai mod mi)
    ll china(ll n, ll *a,ll *m) {
        ll M=1,y,x=0,d;
        for(ll i = 1; i <= n; i++) M *= m[i];
        for(ll i = 1; i <= n; i++) {
            ll w = M /m[i];
            exgcd(m[i], w, d, y);//m[i]*d+w*y=1
            x = (x + y*w*a[i]) % M;
        }
        return (x+M)%M;
    }

    筛素数:

    //7.筛素数,全局:int cnt,prime[N],p[N];
    void isprime() {
        cnt = 0;
        memset(prime,true,sizeof(prime));
        for(int i=2; i<N; i++) {
            if(prime[i]) {
                p[cnt++] = i;
                for(int j=i+i; j<N; j+=i)
                    prime[j] = false;
            }
        }
    }

    快速计算逆元:

    //8.快速计算逆元
    //补充:>>关于快速算逆元的递推式的证明<< 
    void inverse() {
        inv[1] = 1;
        for(int i=2; i<N; i++) {
            if(i >= M) break;
            inv[i] = (M-M/i)*inv[M%i]%M;
        }
    }

    组合数取模:

    //9.组合数取模
    n和m 10^5时,预处理出逆元和阶乘
    ll fac[N]= {1,1},inv[N]= {1,1},f[N]= {1,1};
    ll C(ll a,ll b) {
        if(b>a)return 0;
        return fac[a]*inv[b]%M*inv[a-b]%M;
    }
    void init() { //快速计算阶乘的逆元
        for(int i=2; i<N; i++) {
            fac[i]=fac[i-1]*i%M;
            f[i]=(M-M/i)*f[M%i]%M;
            inv[i]=inv[i-1]*f[i]%M;
        }
    }
    n较大10^9,但是m较小10^5时,
    ll C(ll n,ll m) {
        if(m>n)return 0;
        ll ans=1;
        for(int i=1; i<=m; i++)
            ans=ans*(n-i+1)%M*qpow(i,M-2,M)%M;
        return ans;
    }
    
    //n和m特别大10^18时但是p较小10^5时用lucas

    Lucas大组合取模:

    //10.Lucas大组合取模 
    
    #define N 100005
    #define M 100007
    ll n,m,fac[N]= {1};
    ll C(ll n,ll m) {
        if(m>n)return 0;
        return fac[n]*qpow(fac[m],M-2,M)%M*qpow(fac[n-m],M-2,M)%M;//费马小定理求逆元
    }
    ll lucas(ll n,ll m) {
        if(!m)return 1;
        return(C(n%M,m%M)*lucas(n/M,m/M))%M;
    }
    void init() {
        for(int i=1; i<=M; i++)
            fac[i]=fac[i-1]*i%M;
    }

    质因数分解:

    //11.质因数分解
    cin>>n;
    for(int i=2; i<=n; i++) {
        if(n==0)break;
        while(n%i==0) {
            n/=i;
            k[++ans]=i;
        }
    }

    试除法:

    //12.试除法
    bool check(int n) {
        if(n==1)return false;
        for(int i=2; i<=sqrt(n); ++i)
            if(n%i==0)return false;
        return true;
    }

    miller-rabin算法:

    //13.miller-rabin算法
    int test[10]= {2,3,5,7,11,13,19,23};
    int qpow(int a,int b,int p) {
        int ans=1;
        while(b) {
            if(b&1)ans=1ll*ans*a%p;
            a=1ll*a*a%p,b>>=1;
        }
        return ans;
    }
    bool miller_rabin(int p) {
        if(p==1)return 0;
        int t=p-1;
        k=0;
        while(!(t&1))k++,t>>=1;
        for(int i=0; i<8; ++i) {
            if(p==test[i])return 1;
            long long a=qpow(test[i],t,p,),nx=a;
            for(int j=1; j<=k; ++j) {
                nx=(a*a)%p;
                if(nx==1&&a!=1&&a!=p-1)
                    return 0;
                a-nx;
            }
            if(a!=1)return 0;
        }
        return 1;
    }

    快读:

    //14.快读
    
    inline int read() {
        int s=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {
            if(ch=='-')w=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
            x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
        return s*w;
    }

    spfa_dfs:

    //15.spfa_dfs
    
    int spfa_dfs(int u) {
        vis[u]=1;
        for(int k=f[u]; k!=0; k=e[k].next) {
            int v=e[k].v,w=e[k].w;
            if( d[u]+w < d[v] ) {
                d[v]=d[u]+w;
                if(!vis[v]) {
                    if(spfa_dfs(v))
                        return 1;
                } else
                    return 1;
            }
        }
        vis[u]=0;
        return 0;
    }

    spfa_dfs:

    //16、spfa_bfs
    int spfa_bfs(int s) {
        queue <int> q;
        memset(d,0x3f,sizeof(d));
        d[s]=0;
        memset(c,0,sizeof(c));
        memset(vis,0,sizeof(vis));
    
        q.push(s);
        vis[s]=1;
        c[s]=1;
        //顶点入队vis要做标记,另外要统计顶点的入队次数
        int OK=1;
        while(!q.empty()) {
            int x;
            x=q.front();
            q.pop();
            vis[x]=0;
            //队头元素出队,并且消除标记
            for(int k=f[x]; k!=0; k=nnext[k]) { //遍历顶点x的邻接表
                int y=v[k];
                if( d[x]+w[k] < d[y]) {
                    d[y]=d[x]+w[k];  //松弛
                    if(!vis[y]) { //顶点y不在队内
                        vis[y]=1;    //标记
                        c[y]++;      //统计次数
                        q.push(y);   //入队
                        if(c[y]>NN)  //超过入队次数上限,说明有负环
                            return OK=0;
                    }
                }
            }
        }
    
        return OK;
    
    }

    欧拉函数:

     1 for(i=1; i<=maxn; i++)
     2     p[i]=i;
     3 for(i=2; i<=maxn; i+=2)
     4     p[i]/=2;
     5 for(i=3; i<=maxn; i+=2)
     6     if(p[i]==i)
     7     {
     8         for(j=i; j<=maxn; j+=i)
     9             p[j]=p[j]/i*(i-1);
    10     }

     裴蜀定理:

    1 std::cin>>n;
    2 for(int i=1;i<=n;i++){
    3     int x;
    4     std::cin>>x;
    5     x=std::abs(x);
    6     ans=gcd(ans,x);
    7 }
    8 std::cout<<ans;
    9 PS:自己敲的

    杂:

    //cin,优化
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    //输出优化:
    void print( int k ) {
        num = 0;
        while( k > 0 ) ch[++num] = k % 10, k /= 10;
        while( num )
            putchar( ch[num--]+48 );
        putchar( 32 );
    }

    RMQ:

    //区间查询最值问题
    //预处理
    void rmq_init() {
        for(int i=1; i<=N; i++)
            dp[i][0]=arr[i];//初始化
        for(int j=1; (1<<j)<=N; j++)
            for(int i=1; i+(1<<j)-1<=N; i++)
                dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
    
    }
    //查询 
    int rmq(int l,int r) {
        int k=log2(r-l+1);
        return min(dp[l][k],dp[r-(1<<k)+1][k]);
    }

    RMQ转LCA:

    int euler[MAXN*2];
    int dep[MAXN*2];
    int pos[MAXN];
    int top;
    int rmq[MAXN*2][16];
    void dfs(int u,int depth,int fa)
    {
        euler[++top]=u;
        dep[top]=depth;
        pos[u]=top;
        INE(i,u,e)
        {
            int v=e[i].v;
            if(v==fa) continue;
            dfs(v,depth+1,u);
            euler[++top]=u;
            dep[top]=depth;
        }
    }
    void RMQinit()
    {
        rep(i,1,top) rmq[i][0]=i;
        rep(j,1,16)
        rep(i,1,top) if(i+(1<<j)-1<=top)
        {
            if(dep[rmq[i][j-1]]<dep[rmq[i+(1<<j-1)][j-1]])
                rmq[i][j]=rmq[i][j-1];
            else
                rmq[i][j]=rmq[i+(1<<j-1)][j-1];
        }
    }
    int RMQ(int l,int r)
    {
        int len=r-l+1;
        int LOG=0;
        for(;1<<LOG+1<=len;LOG++);
        if(dep[rmq[l][LOG]]<dep[rmq[r-(1<<LOG)+1][LOG]])
            return rmq[l][LOG];
        else
            return rmq[r-(1<<LOG)+1][LOG];
    }
    void LCAinit()
    {
        dfs(1,0,-1);
        RMQinit();
    }
    int LCA(int u,int v)
    {
        if(pos[u]>pos[v]) swap(u,v);
        return euler[RMQ(pos[u],pos[v])];
    } 

    tarjan求LCA:

    //并查集记录父亲的数组.
    int father[MAXN];
    
    //并查集的查找函数,有路径压缩功能.
    int find ( int x ) {
        return father[x] == x ? x : father[x] = find ( father[x]);
    }
    
    //采用邻接表存储
    struct {
        int v,next,lca,u;
    } e[2][MAXN<<2];
    
    //分别记录边对和查询数对
    int head[2][MAXN];
    int cc;
    
    //添加边,flag表示模式
    void add ( int flag , int u , int v ) {
        e[flag][cc].u = u;
        e[flag][cc].v = v;
        e[flag][cc].next = head[flag][u];
        head[flag][u] = cc++;
    }
    //标记当前点是否访问过
    bool visited[MAXN];
    
    void LCA ( int u ) {
        father[u] = u;
        visited[u] = true;
        //深度优先搜索整棵树
        for ( int i = head[0][u]; i != -1 ; i = e[0][i].next ) {
            int v = e[0][i].v;
            if ( visited[v] ) continue;
            LCA ( v );
            //从叶节点开始,逐层标记父节点
            father[v] = u;
        }
        //当前子树已经维护,利用并查集找到当前子树的查询数对的LCA
        for ( int i = head[1][u]; i != -1 ; i = e[1][i].next ) {
            int v = e[1][i].v;
            if ( !visited[v] ) continue;
            //如果当前u,v都已经访问过,那么一定维护过的子树中
            e[1][i].lca = e[1][i^1].lca = find ( v );
        }
    }

    倍增求LCA:

    #include<bits/stdc++.h>
    using namespace std;
    struct node {
        int t,nex;
    } e[500001<<1];
    int depht[500001],father[500001][22],lg[500001],head[500001];
    int tot;
    inline void add(int x,int y) {
        e[++tot].t=y;
        e[tot].nex=head[x];
        head[x]=tot;
    }
    inline void dfs(int now,int fath) {
        depht[now]=depht[fath]+1;
        father[now][0]=fath;
        for(register int i=1; (1<<i)<=depht[now]; ++i)
            father[now][i]=father[father[now][i-1]][i-1];
        for(register int i=head[now]; i; i=e[i].nex) {
            if(e[i].t!=fath)dfs(e[i].t,now);
        }
    }
    inline int lca(int x,int y) {
        if(depht[x]<depht[y])
            swap(x,y);
        while(depht[x]>depht[y])
            x=father[x][lg[depht[x]-depht[y]]-1];
        if(x==y)
            return x;
        for(register int k=lg[depht[x]]; k>=0; --k)
            if(father[x][k]!=father[y][k])
                x=father[x][k],y=father[y][k];
        return father[x][0];
    }
    int n,m,s;
    int main() {
        scanf("%d%d%d",&n,&m,&s);
        for(register int i=1; i<=n-1; ++i) {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(s,0);
        for(register int i=1; i<=n; ++i)
            lg[i]=lg[i-1]+(1<<lg[i-1]==i);
        for(register int i=1; i<=m; ++i) {
            int x,y;
            scanf("%d%d",&x,&y);
            printf("%d
    ",lca(x,y));
        }
        return 0;
    }
    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define INF 0x3f3f3f3f
    #define MAXN 1000010
    #define MAXM 5010
    
    inline int read()
    {
        int x = 0,ff = 1;char ch = getchar();
        while(!isdigit(ch))
        {
            if(ch == '-') ff = -1;
            ch = getchar();
        }
        while(isdigit(ch))
        {
            x = (x << 1) + (x << 3) + (ch ^ 48);
            ch = getchar();
        }
        return x * ff;
    }
    
    inline void write(int x)
    {
        if(x < 0) putchar('-'),x = -x;
        if(x > 9) write(x / 10);
        putchar(x % 10 + '0');
    }
    
    int a,ti = 0,cnt = 0,fa[MAXN],vis[MAXN],loop[MAXN];
    int lin[MAXN],tot = 0;
    struct edge
    {
        int y,v,next;
    }e[MAXN];
    
    inline void add(int xx,int yy,int vv)
    {
        e[++tot].y = yy;
        e[tot].v = vv;
        e[tot].next = lin[xx];
        lin[xx] = tot;
    }
    
    void get_loop(int x)
    {
        vis[x] = ++ti;
        for(int i = lin[x],y;i;i = e[i].next)
        {
            if((y = e[i].y) == fa[x]) continue;
            if(vis[y])
            {
                if(vis[y] < vis[x]) continue;
                loop[++cnt] = y;
                for(y = fa[y];y != fa[x];y = fa[y])
                loop[++cnt] = y;    
            }
            else fa[y] = x,get_loop(y);
        }
    } 
    
    int main()
    {
        a = read();
        for(int i = 1;i <= a;++i)
        {
            int y,v;
            y = read(); v = read();
            add(i,y,v);
            add(y,i,v);
        }
        get_loop(1);
        for(int i = 1;i <= cnt;++i)
        write(loop[i]),putchar(' '); 
        return 0;
    }
    基环树找环
    //18.tarjan
    void Tarjan ( int x ) {
        dfn[ x ] = ++dfs_num ;
        low[ x ] = dfs_num ;
        vis [ x ] = true ;//是否在栈中
        stack [ ++top ] = x ;
        for ( int i=head[ x ] ; i!=0 ; i=e[i].next ) {
            int temp = e[ i ].to ;
            if ( !dfn[ temp ] ) {
                Tarjan ( temp ) ;
                low[ x ] = gmin ( low[ x ] , low[ temp ] ) ;
            } else if ( vis[ temp ])low[ x ] = gmin ( low[ x ] , dfn[ temp ] ) ;
        }
        if ( dfn[ x ]==low[ x ] ) {//构成强连通分量
            vis[ x ] = false ;
            color[ x ] = ++col_num ;//染色
            while ( stack[ top ] != x ) {//清空
                color [stack[ top ]] = col_num ;
                vis [ stack[ top-- ] ] = false ;
            }
            top -- ;
        }
    }
    tarjan模板
    #include<bits/stdc++.h>
    #define MAXN 501
    const int Big_B = 10; const int Big_L = 1;
    inline int intcmp_ (int a, int b) { if (a > b) return 1; return a < b ? -1 : 0; }
    struct Int 
    {
    #define rg register
        inline int max (int a, int b) { return a > b ? a : b; }
        inline int min (int a, int b) { return a < b ? a : b; }
        std :: vector <int> c; Int () {} typedef long long LL; 
        Int (int x) { for (; x > 0; c.push_back (x % Big_B), x /= Big_B); }
        Int (LL x) { for (; x > 0; c.push_back (x % Big_B), x /= Big_B); }
        inline void CrZ () { for (; !c.empty () && c.back () == 0; c.pop_back ()); }
        inline Int &operator += (const Int &rhs){
            c.resize (max (c.size (), rhs.c.size ())); rg int i, t = 0, S;
            for (i = 0, S = rhs.c.size (); i < S; ++ i)
                c[i] += rhs.c[i] + t, t = c[i] >= Big_B, c[i] -= Big_B & (-t);
            for (i = rhs.c.size (), S = c.size (); t && i < S; ++ i)
                c[i] += t, t = c[i] >= Big_B, c[i] -= Big_B & (-t);
            if (t) c.push_back (t); return *this;
        }
        inline Int &operator -= (const Int &rhs){
            c.resize (max (c.size (), rhs.c.size ())); rg int i, t = 0, S;
            for (i = 0, S = rhs.c.size (); i < S; ++ i)
                c[i] -= rhs.c[i] + t, t = c[i] < 0, c[i] += Big_B & (-t);
            for (i = rhs.c.size (), S = c.size (); t && i < S; ++ i)
                c[i] -= t, t = c[i] < 0, c[i] += Big_B & (-t);
            CrZ (); return *this;
        }
        inline Int &operator *= (const Int &rhs){
            rg int na = c.size (), i, j, S, ai; 
            c.resize (na + rhs.c.size ()); LL t;
            for (i = na - 1; i >= 0; -- i){
                ai = c[i], t = 0, c[i] = 0;
                for (j = 0, S = rhs.c.size (); j < S; ++ j){
                    t += c[i + j] + (LL) ai * rhs.c[j];
                    c[i + j] = t % Big_B, t /= Big_B;
                }
                for (j = rhs.c.size (), S = c.size (); t != 0 && i + j < S; ++ j)
                    t += c[i + j], c[i + j] = t % Big_B, t /= Big_B;
                assert (t == 0);
            }
            CrZ (); return *this;
        }
        inline Int &operator /= (const Int &rhs) { return *this = div (rhs); }
        inline Int &operator %= (const Int &rhs) { return div (rhs), *this; }
        inline Int &shlb (int l = 1){
            if (c.empty ()) return *this; c.resize (c.size () + l);rg int i;
            for (i = c.size () - 1; i >= l; -- i) c[i] = c[i - l];
            for (i = 0; i < l; ++ i) c[i] = 0;
            return *this;
        }
        inline Int &shrb (int l = 1){
            for (rg int i = 0; i < c.size () - l; ++ i) c[i] = c[i + l];
            c.resize (max (c.size () - l, 0)); return *this;
        }
        inline Int div (const Int &rhs){
            assert (!rhs.c.empty ()); Int q, r; rg int i; if (rhs > *this) return 0;
            q.c.resize (c.size () - rhs.c.size () + 1); rg int _l, _r, mid;
            for (i = c.size () - 1; i > c.size () - rhs.c.size (); -- i) r.shlb (), r += c[i];
            for (i = c.size () - rhs.c.size (); i >= 0; -- i){
                r.shlb (); r += c[i]; 
                if (r.Comp (rhs) < 0) q.c[i] = 0;
                else {
                    _l = 0, _r = Big_B;
                    for (; _l != _r; ){
                        mid = _l + _r >> 1;
                        if ((rhs * mid).Comp (r) <= 0) _l = mid + 1; else _r = mid;
                    }
                    q.c[i] = _l - 1, r -= rhs * q.c[i];
                }
            }
            q.CrZ (), *this = r; return q;
        }
        inline int Comp (const Int &rhs) const {
            if (c.size () != rhs.c.size ()) return intcmp_ (c.size (), rhs.c.size ());
            for (rg int i = c.size () - 1; i >= 0; -- i) 
                if (c[i] != rhs.c[i]) return intcmp_ (c[i], rhs.c[i]);
            return 0;
        }
        friend inline Int operator + (const Int &lhs, const Int &rhs)
        { Int res = lhs; return res += rhs; }
        inline friend Int operator - (const Int &lhs, const Int &rhs){ 
            if (lhs < rhs){
                putchar ('-'); 
                Int res = rhs; return res -= lhs;
            }
            else { Int res = lhs; return res -= rhs; }
        }
        friend inline Int operator * (const Int &lhs, const Int &rhs)
        { Int res = lhs; return res *= rhs; }
        friend inline Int operator / (const Int &lhs, const Int &rhs)
        { Int res = lhs; return res.div (rhs); }
        friend inline Int operator % (const Int &lhs, const Int &rhs)
        { Int res = lhs; return res.div (rhs), res; }
        friend inline std :: ostream &operator << (std :: ostream &out, const Int &rhs){ 
            if (rhs.c.size () == 0) out << "0";
            else {
                out << rhs.c.back ();
                for (rg int i = rhs.c.size () - 2; i >= 0; -- i)
                    out << std :: setfill ('0') << std :: setw (Big_L) << rhs.c[i];
            }
            return out;
        } 
        friend inline std :: istream &operator >> (std :: istream &in, Int &rhs){
            static char s[100000];
            in >> s + 1; int Len = strlen (s + 1);
            int v = 0; LL r = 0, p = 1;
            for (rg int i = Len; i >= 1; -- i){
                ++ v; r = r + (s[i] - '0') * p, p *= 10;
                if (v == Big_L) rhs.c.push_back (r), r = 0, v = 0, p = 1;
            }
            if (v != 0) rhs.c.push_back (r); return in;
        }
        friend inline bool operator < (const Int &lhs, const Int &rhs)
        { return lhs.Comp (rhs) < 0; }
        friend inline bool operator <= (const Int &lhs, const Int &rhs)
        { return lhs.Comp (rhs) <= 0; }
        friend inline bool operator > (const Int &lhs, const Int &rhs)
        { return lhs.Comp (rhs) > 0; }
        friend inline bool operator >= (const Int &lhs, const Int &rhs)
        { return lhs.Comp (rhs) >= 0; }
        friend inline bool operator == (const Int &lhs, const Int &rhs)
        { return lhs.Comp (rhs) == 0; }
        friend inline bool operator != (const Int &lhs, const Int &rhs)
        { return lhs.Comp (rhs) != 0; }
    #undef rg    
    };
    int Main (){
        return 0;
    }
    int ZlycerQan = Main ();
    int main (int argc, char *argv[]) {;}
    高精板子
        queue<int>q;
        vector<int>edge[n];
        for(int i=0;i<n;i++)  //n  节点的总数
            if(in[i]==0) q.push(i);  //将入度为0的点入队列
        vector<int>ans;   //ans 为拓扑序列
        while(!q.empty())
        {
            int p=q.front(); q.pop(); // 选一个入度为0的点,出队列
            ans.push_back(p);
            for(int i=0;i<edge[p].size();i++)
            {
                int y=edge[p][i];
                in[y]--;
                if(in[y]==0)
                    q.push(y);  
            }
        }
        if(ans.size()==n)   
        {
            for(int i=0;i<ans.size();i++)
                printf( "%d ",ans[i] );
            printf("
    ");
        }
        else printf("No Answer!
    ");  
    拓扑排序

    有关最短路的东西:

    //一、多源最短路算法——Floyd 算法
    //floyd 算法主要用于求任意两点间的最短路径,也称最短最短路径问题
    //核心代码:
    void floyd() {
        int i, j, k;
        for (k = 1; k <= n; ++k) //遍历所有的中间点
            for (i = 1; i <= n; ++i) //遍历所有的起点
                for (j = 1; j <= n; ++j) //遍历所有的终点
                    if (e[i][j] > e[i][k] + e[k][j]) //如果当前i-->j的距离大于i-->k--->j的距离之和
                        e[i][j] = e[i][k] + e[k][j];//更新从i--->j的最短路径
    }
    //  时间复杂度:O(N^3)
    //  不能使用的情况:边中含有负权值
    
    
    
    //二、单源最短路径算法——dijkstra
    //1、思想描述:当Q(一开始为所有节点的集合)非空时,
    //不断地将Q中的最小值u取出,然后放到S(最短路径的节点的集合)集合中,
    //然后遍历所有与u邻接的边,如果可以进行松弛,
    //则对便进行相应的松弛。。。
    //2、实现
    /**
     * 返回从v---->到target的最短路径
     */
    int dijkstra(int v) {
        int i;
        for(i = 1 ; i <= n ; ++i) { //初始化
            s[i] = 0;//一开始,所有的点均为被访问过
            dis[i] = map[v][i];
        }
        dis[v] = 0;
        s[v] = true;
        for(i = 1 ; i < n ; ++i) {
            int min = inf,pos,j;
            for(j = 1 ; j <= n ; ++j)//寻找目前的最短路径的最小点
                if(!s[j] && dis[j] < min) {
                    min = dis[j];
                    pos = j;
                }
            s[pos] = 1;
            for(j = 1 ; j <= n ; j++)//遍历u的所有的邻接的边
                if(!s[j] && dis[j] > dis[pos] + map[pos][j])
                    dis[j] = dis[pos] + map[pos][j];//对边进行松弛
        }
        return dis[target];
    }
    //3.基本结构
    int s[maxn];//用来记录某一点是否被访问过
    int map[maxn][maxn];//地图
    int dis[maxn];//从原点到某一个点的最短距离(一开始是估算距离)
    //4.条件:使用dijkstra解决的题目一般有以下的特征:
    //给出点的数目、边的数目、起点和终点、边的信息(,并且边不包含负边权的值).求从起点到终点的最短路径的距离
    //起点:用于dijkstra(int v)中的v
    //终点:用于return dis[target]中的target
    //边的信息:用于初始化map[][]
    
    //三:使用 bellmen-ford 算法
    //算法介绍:
    //思想:其实bellman-ford的思想和dijkstra的是很像的,
    //其关键点都在于不断地对边进行松弛。
    //而最大的区别就在于前者能作用于负边权的情况。
    //其实现思路还是在求出最短路径后,
    //判断此刻是否还能对便进行松弛,
    //如果还能进行松弛,便说明还有负边权的边
    //实现:
    bool  bellmen_ford() {
        for(int i=1; i<=n; i++)
            dis[i]=inf;
        dis[source]=0;
        for(int i=1; i<n; i++) {
            for(int j=1; j<=m; j++) {
                dis[edge[j].v] = min(dis[edge[j].v],dis[edge[j].u] + edge[j].weight);
                dis[edge[j].u] =min(dis[edge[j].u],dis[edge[j].v] + edge[j].weight) ;
            }
        }
        for(j = 1 ; j <= m ; ++j)  //判断是否有负边权的边
            if(dis[edge[j].v] > dis[edge[j].u] + edge[j].weight)
                return false;
        return true;
    }
    //基本结构:
    struct Edge{
        int u,v,weight;
    }edge[maxn];
    int dis[maxn];
    //条件:其实求最短路径的题目的基本条件都是点数,边数,起点终点
    
    
    //四、使用spfa算法来解决
    //思想:用于求单源最短路经,可以适用于负边权的情况(不过他已经死了 
    View Code

     大佬给的网站:Graph Editor

  • 相关阅读:
    来自1068
    耻辱的时间戳(笑哭)
    依然排序
    呵呵
    好吧,第二篇
    来自机房的第一篇博客
    Shader-水流效果
    unity中虚拟摇杆的实现
    (转载)Unity3d中的属性(Attributes)整理
    C#冒泡排序法及优化
  • 原文地址:https://www.cnblogs.com/ydclyq/p/11663597.html
Copyright © 2011-2022 走看看