zoukankan      html  css  js  c++  java
  • 图论基本模板总结

    最短路(vector+Dijkstra优先队列优化)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    #include<vector>
    #include<cmath>
    #define Inf 0x3f3f3f3f
    
    const int maxn=1e5+5;
    typedef long long ll;
    using namespace std;
    
    struct node
    {
        int pos;
        int w;
        node (int x,int y)
        {
            pos=x;
            w=y;
        }
        bool friend operator < (node x,node y)
        {
            return x.w>y.w;
        }
    };
    vector<node>vec[10005];
    int dis[10005];
    int vis[10005];
    int n,m;
    void init()
    {
        for(int t=1;t<=n;t++)
        {
            dis[t]=Inf;
        }
        memset(vis,0,sizeof(vis));
    }
    
    void Dijkstra(int s)
    {
        priority_queue<node>q;
        q.push(node(s,0));
        dis[s]=0;
        while(!q.empty())
        {
            node now=q.top();
            q.pop();
            if(vis[now.pos])continue;
            vis[now.pos]=1;
            for(int t=0;t<vec[now.pos].size();t++)
            {
                node to=vec[now.pos][t];
                if(to.w+dis[now.pos]<dis[to.pos])
                {
                    dis[to.pos]=to.w+dis[now.pos];
                    to.w=dis[to.pos];
                    q.push(to);
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        init();
        int u,v,w;
        for(int t=0;t<m;t++)
        {
            scanf("%d%d%d",&u,&v,&w);
            vec[u].push_back(node(v,w));
            vec[v].push_back(node(u,w));
        }
        Dijkstra(n);
        printf("%d
    ",dis[1]);
        return 0;
    }

    邻接表+DIjkstra队列优化

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<set>
    #include<vector>
    #include<map>
    #include<cmath>
    #define Inf 0x3f3f3f3f
    const int maxn=1e5+5;
    typedef long long ll;
    using namespace std;
    struct edge
    {
        int u,v,w;
        int next;
    }Edge[10*maxn];
    
    struct node
    {
        int pos,w;
        node(int x,int y)
        {
            pos=x;
            w=y;
        }
        bool friend operator < (node x,node y)
        {
            return x.w>y.w;
        }
    };
    int head[1005],dis[1005],vis[1005],cnt=0;
    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++;
    }
    void Dijkstra(int s)
    {
        dis[s]=0;
        priority_queue<node>q;
        q.push(node(s,0));
        while(!q.empty())
        {
            node now=q.top();
            q.pop();
            if(vis[now.pos])continue;
            vis[now.pos]=1;
            
            for(int i=head[now.pos];i!=-1;i=Edge[i].next)
            {
                if(dis[now.pos]+Edge[i].w<dis[Edge[i].v])
                {
                    dis[Edge[i].v]= dis[now.pos]+Edge[i].w;
                    q.push(node(Edge[i].v,dis[Edge[i].v]));
                } 
            }
        } 
        return ;
    }
    int main()
    {
       int m,n;
       cin>>n>>m;
       int u,v,w;
       memset(head,-1,sizeof(head));
       memset(dis,Inf,sizeof(dis)); 
       for(int t=0;t<m;t++)
       {
           scanf("%d%d%d",&u,&v,&w);
           add(u,v,w);
           add(v,u,w);
       }
       Dijkstra(n);
       printf("%d
    ",dis[1]);
       return 0;
    }

    SPFA判负环

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    #include<vector>
    #include<cmath>
    #define Inf 0x3f3f3f3f
    
    const int maxn=1e5+5;
    typedef long long ll;
    using namespace std;
    
    struct Edge
    {
        int u,v,w;
        int next;
    }edge[7499];
    int head[505],vis[505],cnt[505],dis[505],tot;
    void init()
    {
        memset(head,-1,sizeof(head));
        memset(cnt,0,sizeof(cnt));
        memset(vis,0,sizeof(vis));
        memset(dis,Inf,sizeof(dis));
    }
    void add(int u,int v,int w)
    {
        edge[tot].u=u;
        edge[tot].v=v;
        edge[tot].w=w;
        edge[tot].next=head[u];
        head[u]=tot++;
        return;
    }
    int n,m,k; 
    bool SPFA(int s)
    {
        dis[s]=0;
        cnt[s]=1;
        vis[s]=true;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            vis[now]=false;
            for(int i=head[now];i!=-1;i=edge[i].next)
            {
                if(dis[now]+edge[i].w<dis[edge[i].v])
                {
                    dis[edge[i].v]= dis[now]+edge[i].w;
                    int y=edge[i].v;
                    cnt[y]=cnt[now]+1;
                    if(cnt[y]>n)
                    {
                        return true;
                    }
                    if(vis[y]==false)
                    {
                      vis[y]=true;
                      q.push(y);
                    }
                }
            }
        }
        return false;
        
    }
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
          tot=0;
          init();
          scanf("%d%d%d",&n,&m,&k);
          int u,v,w;
          for(int t=0;t<m;t++)
          {
              scanf("%d%d%d",&u,&v,&w);
              add(u,v,w);
              add(v,u,w);
          }
          for(int t=0;t<k;t++)
          {
              scanf("%d%d%d",&u,&v,&w);
              add(u,v,-w);
          }
          if(SPFA(1))
          {
              puts("YES");
          }
          else
          {
              puts("NO");
          }
          
        } 
        
    } 

    拓扑排序判环

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<set>
    #include<vector>
    #include<map>
    #include<cmath>
    const int maxn=1e5+5;
    typedef long long ll;
    using namespace std;
    int du[105];
    vector<int>vec[105];
    int n,m;
    bool TPsort()
    {
        queue<int>q;
        int cnt=0;
        for(int t=0;t<n;t++)
        {
            if(du[t]==0)
            {
                q.push(t);
            }
        }
        while(!q.empty())
        {
            int now=q.front();
            q.pop();
            cnt++;
            for(int t=0;t<vec[now].size();t++)
            {
                int nxt=vec[now][t];
                du[nxt]--;
                if(du[nxt]==0)
                {
                    q.push(nxt);
                }
            }
        }
        if(cnt!=n)
        {
            return false; 
        }
        else
        {
            return true;
        }
    }
    int main()
    {
       while(scanf("%d%d",&n,&m)!=EOF)
       {
            if(n==0)
            {
                break;
         }
            memset(du,0,sizeof(du));
            for(int t=0;t<n;t++)
            {
                vec[t].clear();
        }
            int u,v;
         for(int t=0;t<m;t++)
         {
             scanf("%d%d",&u,&v);
             vec[u].push_back(v);
             du[v]++;
         }
         if(TPsort())
         {
             puts("YES");
         }
         else
         {
             puts("NO");
         }
       }
       return 0;
    }

    树的直径

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<set>
    #include<map>
    #include<vector>
    #define Inf 0x3f3f3f3f
    
    const int maxn=1e4+5;
    typedef long long ll;
    using namespace std;
    struct edge
    {
        int to,cost;
    };
    
    vector<edge> e[maxn];
    int farthest,ans;
    void dfs(int x,int pre,int dis)
    {
        for(int i=0;i<e[x].size();i++)
        {
            int xx = e[x][i].to;
            if(xx == pre)
                continue;
            dfs(xx,x,dis+e[x][i].cost);
        }
        if(dis > ans)
        {
            ans = dis;
            farthest = x;
        }
    }
    int main()
    {
            int i,j;
           
            int x,y;
            edge t;
               while(scanf("%d%d%d",&x,&y,&t.cost)!=EOF)
               {
                t.to = y;
                e[x].push_back(t);
                t.to = x;
                e[y].push_back(t);
                }
            ans = 0;
            dfs(1,-1,0);
            
            dfs(farthest,-1,0);
            printf("%d
    ",ans);
        
     
        return 0;
    }
     
  • 相关阅读:
    zoj 1239 Hanoi Tower Troubles Again!
    zoj 1221 Risk
    uva 10192 Vacation
    uva 10066 The Twin Towers
    uva 531 Compromise
    uva 103 Stacking Boxes
    稳定婚姻模型
    Ants UVA
    Golden Tiger Claw UVA
    关于upper、lower bound 的探讨
  • 原文地址:https://www.cnblogs.com/Staceyacm/p/11266858.html
Copyright © 2011-2022 走看看