图论基础算法

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]));
            }
        }
    }
}

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;
    }
};

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;

第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\n"); continue; }
        if(be==en) K++;
        printf("%d\n",solve(be));
    }
    return 0;
}

最优比例生成树

#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\n",solve());
    }
    return 0;
}

时间: 2024-08-29 12:22:23

图论基础算法的相关文章

REcheck 图论基础算法

真是搞懂了 声明: struct edge { int y,v,next; }e[maxn+100]; int link[maxn+100]; int len=0; void push(int xx,int yy,int vv){ e[++len].next=link[xx]; link[xx]=len;e[len].v=vv;e[len].y=yy;} int main() { F(i,1,n) { scanf("%d%d%d",&xx,&yy,&zz); p

九章算法 基础算法 强化算法 系统设计 大数据 安卓 leetcode 高清视频

leetcode 直播视频讲座录像 九章算法视频录像,PPT 算法班,算法强化班,Java入门与基础算法班,big data项目实战班,Andriod项目实战班 九章算法下载 九章算法面试 九章算法leetcode 九章算法答案 九章算法mitbbs 九章算法班 九章算法ppt 九章算法录像 九章算法培训 九章算法微博 leetcode 视频 九章算法偷录 算法培训 算法班课程大纲: 1 从strStr谈面试技巧与Coding Style(免费试听) 2 二分搜索与旋转排序数组 Binary S

数据结构:图论基础

图概述 图(Graph)是一种比线性结构和树形结构都要复杂的数据结构.简单讲,图是由表示数据元素的的集合V和表示数据之间关系的集合E组成.其中,数据元素常称作顶点(vertex),数据之间的关系常称作边(edge).故图可记为G=<V,E>,其中V是顶点的有穷非空集合,E是边的集合.在图中顶点的前驱和后继是不设限制的,因此图描述的是一种网状关系. 无向图 若边是无序的或者说是无向的,则称此图是无向图.若无向图中有边(v1,v2)(无向图中边用圆括号表示),则显然(v2,v1)和(v1,v2)是

图论基础知识总结

图论基础知识总结 前言 因为博主太菜,好多之前学过的图论算法都要不记得了,于是开了这篇博文提醒自己要记得复习图论. 代码 #include<bits/stdc++.h> using namespace std; #define gc() getchar() inline int In(){ char c=gc(); int x=0,ft=1; for(;c<'0'||c>'9';c=gc()) if(c=='-') ft=-1; for(;c>='0'&&c&

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

基础算法之排序--快速排序

1 /************************************************************************************** 2 * Function : 快速排序 3 * Create Date : 2014/04/21 4 * Author : NTSK13 5 * Email : [email protected] 6 * Copyright : 欢迎大家和我一起交流学习,转载请保持源文件的完整性. 7 * 任何单位和个人不经本人允许不

算法录 之 基础算法

这一篇文章主要说说一些基础算法,这些算是很多其他算法的基石. 主要包括  模拟,暴力,枚举,递归,贪心,分治. 1,模拟: 顾名思义,模拟就是...饿,模拟,有一些题目就是给你一些步骤,然后你写代码一步步去模拟那些步骤就行.这类题目主要属于基础题,但是当然如果需要模拟的步骤足够恶心的话,还是比较麻烦的... 具体模拟的例子在之后的练习中会遇到的,按照题目要求一步步做就行,一般算法难度比较小. 2,暴力: 顾名思义,暴力就是...饿,暴力.比如说题目让从平面上的10个点中取三个点,让他们形成的三角

【uva 658】It&#39;s not a Bug, it&#39;s a Feature!(图论--Dijkstra算法+二进制表示)

题意:有n个潜在的bug和m个补丁,每个补丁用长为n的字符串表示.首先输入bug数目以及补丁数目.然后就是对m 个补丁的描述,共有m行.每行首先是一个整数,表明打该补丁所需要的时间.然后是两个字符串,地一个字符串 是对软件的描述,只有软件处于该状态下才能打该补丁该字符串的每一个位置代表bug状态(-代表该位置没bug,+代 表该位置有bug,0表示该位置无论有没有bug都可打补丁).然后第二个字符串是对打上补丁后软件状态的描述 -代表该位置上的bug已经被修复,+表示该位置又引入了一个新的bug

最最最最最最最最基础的C---C简介和基础算法

C简介 C是一门程序设计语言,面向过程的语言.于1972至1973年设计出来的语言. C具有32个关键字,9种控制语句,34种运算符. 函数是C的基本单位:一个C程序的执行总是从main函数开始的. C程序运行步骤:源程序--编译-->目标文件--执行-->可执行目标程序. 基础算法 完整的程序设计=数据结构+算法+程序设计方法+语言工具 算法特效: 1.有穷性:一个算法包含有限的操作步骤 2.确定性:确定算法的每一个步骤都是确定的 3.有零个或多个输入 4.有一个或多个输出 5.有效性:算法