图论基本模板总结

最短路(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\n",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\n",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\n",ans);
    
 
    return 0;
}

 

 

 
posted @ 2019-07-29 22:10  black_hole6  阅读(194)  评论(0编辑  收藏  举报