• spfa


      用前向星链表速度很快

    SPFA有时会被恶意数据卡掉,如果没有负边权的话还是建议使用Dijkstra

    标准:

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define LL long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 2147483647
    #define N 500000+50
    int dis[N],vis[N],head[N],n,m,s,pos,k,L,R,ans;
    struct Edge
    {
        int next,v,to;
    }edge[N];
    void addedge(int a,int b,int c)
    {
        edge[++pos]=Edge{head[a],c,b};
        head[a]=pos;
    }
    void spfa(int s)
    {
        queue<int>q;
        rep(i,1,n)
        dis[i]=inf,vis[i]=0;
    
        q.push(s);
        dis[s]=0;
        vis[s]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            vis[u]=0;
            for(int i=head[u];i;i=edge[i].next)
            {
                int v=edge[i].to;
    
                if(dis[v]>dis[u]+edge[i].v)
                {
                    dis[v]=dis[u]+edge[i].v;
                    if(vis[v]==0)
                    {
                        vis[v]=1;
                        q.push(v);
                    }
                }
            }
        }
    }
    View Code

    判断负权环:

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define ll long long
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    #define inf 0x3f3f3f3f
    #define N 1000+5
    
    struct node
    {
        int to,nex,v;
    }edge[N];
    int pos=0;
    int head[N];
    void add(int a,int b,int c)
    {
        edge[++pos].nex=head[a];
        head[a]=pos;
        edge[pos].v=c;
        edge[pos].to=b;
    }
    int n,m;
    int vis[N];
    int dis[N];
    int cnt[N];
    bool spfa()
    {
        queue<int>q;
        CLR(vis,0);
        CLR(dis,0x3f);
        CLR(cnt,0);
        q.push(n+1);
        dis[n+1]=0;
        vis[n+1]=1;//n+1为起始点
        cnt[n+1]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            vis[u]=0;
            for(int i=head[u];i;i=edge[i].nex)
            {
                int v=edge[i].to;
                if(dis[v]>dis[u]+edge[i].v)
                {
                    dis[v]=dis[u]+edge[i].v;
                    if(!vis[v])
                    {
                        cnt[v]++;
                        if(cnt[v]>n)return 0;
                        q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
        return 1;
    }
    int main()
    {
        while(RI(n),n)
        {
            RI(m);
            CLR(head,0);
            pos=0;
            string str;
            int a,b,k;
            while(m--)
            {
               RII(a,b);cin>>str;RI(k);
               if(str=="gt")
                   add(a+b,a-1,-k-1);
               else add(a-1,a+b,k-1);
            }
            rep(i,1,n)
            add(n+1,i,0);//这里ab顺序反了也会错
            if(spfa())
                printf("lamentable kingdom
    ");
            else printf("successful conspiracy
    ");
        }
        return 0;
    }
    View Code

    bellman判环

    bool bellman_ford(int n, int m)
    {
        //因为是求存不存在负权回路,那么只要初始化为0,更新n遍之后,如果还能再更新,那么就存在
        for(int i=1; i<=n; ++i)
            dist[i] = 0;
        for(int i=1; i<=n; ++i)//n+1个点,所以要更新n遍
        {
            for(int j=0; j<m; ++j)
            {
                Edge &e = es[j];
                //因为图是不连通的,所以如果置为INF的时候,不能在这里加这个条件
                if( dist[e.to] > dist[e.from] + e.dist)
                    dist[e.to] = dist[e.from] + e.dist;
            }
        }
        for(int j=0; j<m; ++j)
        {
            Edge &e = es[j];
            if(dist[e.to] > dist[e.from] + e.dist)
                    return false;
        }
        return true;
    }
    View Code
  • 相关阅读:
    解决phpmailer可以在windows下面发送成功, 在linux下面失败的问题
    centos安装svn
    linux下面配置安装nodejs+npm
    排序与搜索
    链表
    栈和队列
    顺序表
    初识算法、数据结构
    Linux_02
    Linux_01
  • 原文地址:https://www.cnblogs.com/bxd123/p/10685954.html
Copyright © 2020-2023  润新知