zoukankan      html  css  js  c++  java
  • 图论基础算法

    dijkstral堆优化算法

    struct node
    {
        int u,d;
        node(int u=0,int d=0):u(u),d(d){}
        bool operator < (const node& t) const{ return d>t.d; }
    };
    struct edge
    {
        int u,v,w;
        edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){}
    };
    vector<edge> G[maxn];
    priority_queue<node> que;
    int N,D[maxn];
    bool vis[maxn];
    void Dijkstra(int s)
    {
        while(!que.empty()) que.pop();
        for(int i=0;i<=N;i++) D[i]=INF;
        D[s]=0;
        memset(vis,false,sizeof(vis));
        que.push(node(s,0));
        while(!que.empty())
        {
            node t=que.top(); que.pop();
            int u=t.u;
            if(vis[u]) continue;
            vis[u]=true;
            int Size=G[u].size();
            for(int i=0;i<Size;i++)
            {
                edge& e=G[u][i];
                int v=e.v,w=e.w;
                if(D[v]>D[u]+w)
                {
                    D[v]=D[u]+w;
                    que.push(node(v,D[v]));
                }
            }
        }
    }
    View Code

    2SAT紫书模板

    struct TwoSAT
    {
        int n;
        vector<int> G[maxn*2];
        bool mark[maxn*2];
        int S[maxn*2],c;
        bool dfs(int u)
        {
            if(mark[u^1]) return false; //对立面为真,矛盾
            if(mark[u]) return true;
            mark[u]=true;
            S[c++]=u; //记录下来方便后面修改
            int Size=G[u].size();
            for(int i=0;i<Size;i++)
            {
                int v=G[u][i];
                if(!dfs(v)) return false;
            }
            return true;
        }
        void init(int nn)
        {
            n=nn;
            for(int i=0;i<=2*n;i++) G[i].clear(),mark[i]=false;
        }
        void AddNode(int x,int xval,int y,int yval)
        {
            x=x*2+xval;
            y=y*2+yval;
            G[x^1].push_back(y);
            G[y^1].push_back(x);
        }
        bool solve()
        {
            for(int i=0;i<n*2;i+=2)
                if(!mark[i]&&!mark[i+1]) //都没有访问过
                {
                    c=0;
                    if(!dfs(i)) //为假全部翻转
                    {
                        while(c>0) mark[S[--c]]=false;
                        if(!dfs(i+1)) return false; //都矛盾则无解
                    }
                }
            return true;
        }
    };
    View Code

    2SAT的Tarjan写法

    struct TwoSAT
    {
        vector<int> G[2*maxn];
        int dfn[2*maxn],low[2*maxn];
        int KK[2*maxn],b[2*maxn];
        bool vis[2*maxn];
        int scc,top,id,n;
        void init(int nn=maxn-1)
        {
            n=nn;
            for(int i=0;i<=2*n;i++)
            {
                G[i].clear();
                dfn[i]=0;
                vis[i]=false;
            }
            scc=top=id=0;
        }
        void AddEdge(int u,int d1,int v,int d2)
        {
            u=u*2+d1;
            v=v*2+d2;
            G[u].push_back(v);
        }
        void Tarjan(int u)
        {
            dfn[u]=low[u]=++id;
            vis[u]=true;
            KK[++top]=u;
            int v,Size=G[u].size();
            for(int i=0;i<Size;i++)
            {
                v=G[u][i];
                if(!dfn[v])
                {
                    Tarjan(v);
                    low[u]=min(low[u],low[v]);
                }
                else if(vis[v]) low[u]=min(low[u],dfn[v]);
            }
            if(dfn[u]==low[u])
            {
                scc++;
                while(true)
                {
                    v=KK[top--];
                    vis[v]=false;
                    b[v]=scc;
                    if(v==u) break;
                }
            }
        }
        bool judge()
        {
            for(int i=0;i<2*n;i++) if(!dfn[i]) Tarjan(i);
            for(int i=0;i<2*n;i+=2) if(b[i]==b[i+1]) return false;
            return true;
        }
    }sat;
    View Code

    第K短路

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int INF=1e8;
    const int maxn=1001;
    int N,M,be,en,K;
    struct edge
    {
        int v,c,next;
        edge(int v=0,int c=0):v(v),c(c){}
    }E[2][maxn*100];
    int head[2][maxn],eid;
    int dist[maxn];
    int cnt[maxn];
    struct node
    {
        int v,d;
        node(int v=0,int d=0):v(v),d(d){}
        bool operator < (const node& t) const
        { return d+dist[v]>t.d+dist[t.v]; }
    };
    priority_queue<node> que;
    void Dij(int st)
    {
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i<=N;i++) dist[i]=INF;
        dist[st]=0;
        while(!que.empty()) que.pop();
        que.push(node(st,0));
        while(!que.empty())
        {
            node t=que.top(); que.pop();
            int u=t.v;
            if(cnt[u]) continue;
            cnt[u]=1;
            for(int i=head[1][u];i!=-1;i=E[1][i].next)
            {
                int v=E[1][i].v,c=E[1][i].c;
                if(dist[v]>dist[u]+c)
                {
                    dist[v]=dist[u]+c;
                    que.push(node(v,0));
                }
            }
        }
    }
    int solve(int st)
    {
        memset(cnt,0,sizeof(cnt));
        while(!que.empty()) que.pop();
        que.push(node(st,0));
        while(!que.empty())
        {
            node t=que.top(); que.pop();
            int u=t.v,d=t.d;
            cnt[u]++;
            if(cnt[u]==K) return d+dist[u];
            for(int i=head[0][u];i!=-1;i=E[0][i].next)
            {
                int v=E[0][i].v,c=E[0][i].c;
                if(cnt[v]<=K) que.push(node(v,d+c));
            }
        }
        return -1;
    }
    int main()
    {
        while(scanf("%d%d",&N,&M)!=EOF)
        {
            memset(head,-1,sizeof(head));
            int u,v,c;
            eid=0;
            while(M--)
            {
                scanf("%d%d%d",&u,&v,&c);
                E[0][++eid]=edge(v,c);
                E[0][eid].next=head[0][u];
                head[0][u]=eid;
                E[1][eid]=edge(u,c);
                E[1][eid].next=head[1][v];
                head[1][v]=eid;
            }
            scanf("%d%d%d",&be,&en,&K);
            Dij(en);
            if(dist[be]==INF){ printf("-1
    "); continue; }
            if(be==en) K++;
            printf("%d
    ",solve(be));
        }
        return 0;
    }
    View Code

    最优比例生成树

    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int maxn=105;
    const int maxm=10005;
    int N,M;
    double low,up,mid;
    struct edge
    {
        int u,v,w,c;
        edge(int u=0,int v=0,int w=0,int c=0)
        :u(u),v(v),w(w),c(c){}
        bool operator < (const edge& t) const
        {
            return (double)(w-mid*c)<(double)(t.w-mid*t.c);
        }
    }E[maxm];
    int d[maxn];
    int root(int a){ return d[a]==a?a:d[a]=root(d[a]); }
    double Kruskal()
    {
        sort(E,E+M);
        for(int i=0;i<=N;i++) d[i]=i;
        int step=0;
        double ret=0.0;
        for(int i=0;i<M;i++)
        {
            edge& e=E[i];
            int u=e.u,v=e.v,w=e.w,c=e.c;
            int ra=root(u);
            int rb=root(v);
            if(ra==rb) continue;
            d[rb]=ra;
            ret+=(double)(w-mid*c);
            step++;
            if(step==N-1) break;
        }
        return ret;
    }
    double solve()
    {
        low=0,up=10000;
        int cnt=150;
        while(cnt--)
        {
            mid=(low+up)/2;
            if(Kruskal()>0) low=mid;
            else up=mid;
        }
        return low;
    }
    int main()
    {
        while(scanf("%d%d",&N,&M)!=EOF)
        {
            int u,v,w,c;
            for(int i=0;i<M;i++)
            {
                scanf("%d%d%d%d",&u,&v,&w,&c);
                E[i]=edge(u,v,w,c);
            }
            printf("%.4f
    ",solve());
        }
        return 0;
    }
    View Code

    Prim算法

    int prim(int st)
    {
        for(int i=0;i<maxn;i++)  D[i]=INF;
        D[st]=0;
        memset(vis,false,sizeof(vis));
        int ret=0;
        for(int i=0;i<N;i++)
        {
            int pos=-1;
            for(int j=0;j<N;j++)  if(!vis[j]&&(pos==-1||D[j]<D[pos]))  pos=j;
            if(pos==-1)  break;
            vis[pos]=true;
            ret+=D[pos];
            for(int j=0;j<N;j++)  D[j]=min(D[j],dist[pos][j]);
        }
        return ret;
    }
    View Code

    Bellman算法

    int dist[155];
    bool bellman()
    {
        memset(dist,0,sizeof(dist));
        for(int i=1;i<=N;i++)
            for(int j=0;j<M;j++)
            {
                edge& e=save[j];
                if(dist[e.to]>dist[e.from]+e.weight)  dist[e.to]=dist[e.from]+e.weight;
            }
        for(int j=0;j<M;j++)
        {
            {
                edge& e=save[j];
                if(dist[e.to]>dist[e.from]+e.weight)  return false;
            }
        }
        return true;
    
    }
    View Code

    Dijkstra算法

    int dist[35][35],vis[35],D[35];
    int dijkstra(int op)
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=N;i++)  D[i]=INF;
        vis[op]=1;
        D[1]=0;
        while(true)
        {
            int pos=-1;
            for(int i=1;i<=N;i++)  if(!vis[i]&&(pos==-1||D[i]<D[pos]))  pos=i;
            if(pos==-1)  break;
            vis[pos]=1;
            for(int i=1;i<=N;i++)  D[i]=min(D[i],D[pos]+dist[i][pos]);
        }
        return D[N];
    }
    View Code

    spfa算法

    double D[105];
    bool inq[105];
    bool spfa(int start)
    {
         for(int i=1;i<=N;i++)  D[i]=dbinf;
         memset(inq,false,sizeof(inq));
         D[start]=0.0;
         queue<int> que;
         que.push(start);
         while(!que.empty())
         {
             int now=que.front();  que.pop();
             inq[now]=false;
             for(int i=1;i<=N;i++)
                if(i!=now&&dist[i][now]<=10.0&&D[i]>D[now]+dist[i][now])
             {
                 D[i]=D[now]+dist[i][now];
                 if(!inq[i])  { inq[i]=true; que.push(i); }
             }
         }
         for(int i=1;i<=N;i++)
         {
             if(D[i]>10000000.0)  return false;
             ans=max(ans,D[i]);
         }
         return true;
    }
    View Code
  • 相关阅读:
    hdu2083 简易版之最短距离
    android:layout_gravity和android:gravity属性的差别
    java设计模式演示样例
    [CSS] Transition
    [React] React Fundamentals: Precompile JSX
    [React] React Fundamentals: JSX Deep Dive
    [React] React Fundamentals: Build a JSX Live Compiler
    [Angular 2] 8. Better ES5 Code
    [rxjs] Throttled Buffering in RxJS (debounce)
    [rxjs] Demystifying Cold and Hot Observables in RxJS
  • 原文地址:https://www.cnblogs.com/wust-ouyangli/p/5778531.html
Copyright © 2011-2022 走看看