ACM图论模板

基本概念

顶点:表示某个事物或对象

:表示事物与事物之间的关系

有向图:有向图中的边是有方向性的,无向图则没有方向

权重:即每条边都有与之对应的值

路径::一个顶点序列i1,i2........ik是图的一条路径,当且仅当边(i1,i2)(i2,i3).........(ik-1,ik)都在图中。如果除了第一个顶点和最后一个顶点之外,其余的顶点均不相同,那么这条路径称为简单路径

:在路径的终点添加一条指向起点的边,就构成一条环路

连通图:设图G是无向图,当且仅当G的每一对顶点之间都有一条路径,则称G是连通图

强连通图:图G是一个有向图,当且仅当每一对不同的顶点u,v,从u到v和v到u都有一条有向路径

生成树:如果图H是图G的子图,且他们的顶点集合相同,并且H是没有环路的无向连通图(即一棵树),则称H是G的一棵生成树

二分图:图G的顶点被分为两个子集,而且每条边只能从一个子集到另一个子集

有向无环图

/*==================================================*\ 
 | DAG的深度优先搜索标记 
 | INIT: edge[][]邻接矩阵; pre[], post[], tag全置0; 
 | CALL: dfstag(i, n);   pre/post:开始/结束时间 
\*==================================================*/ 
int edge[V][V], pre[V], post[V], tag; 
void dfstag(int cur, int n) 
{  // vertex: 0 ~ n-1  
    pre[cur] = ++tag;  
    for (int i=0; i<n; ++i) if (edge[cur][i]) {   
        if (0 == pre[i]) {    
            printf("Tree Edge!\n");    
            dfstag(i, n);   
        } else {    
            if (0 == post[i])  printf("Back Edge!\n");    
            else if (pre[i] > pre[cur])  printf("Down Edge!\n");    
            else  printf("Cross Edge!\n");   
        }  
    }  
    post[cur] = ++tag; 
}

拓扑排序

/*==================================================*\ 
 | 拓扑排序 
 | INIT:edge[][]置为图的邻接矩阵;count[0…i…n-1]:顶点i的入度. 
\*==================================================*/ 
void TopoOrder(int n){  
    int  i, top = -1;  
    for( i=0; i < n; ++i ) {
        if( count[i] == 0 ) { // 下标模拟堆栈 
            count[i] = top; top = i;   
        }  
        for( i=0; i < n; ++i ) {
            if( top == -1 ) {
                printf("存在回路\n"); 
                return ; 
            } else {    
                int j = top; top = count[top];    
                printf("%d", j);    
                for( int k=0; k < n; ++k )     
                    if( edge[j][k] && (--count[k]) == 0  ){      
                        count[k] = top; top = k;     
                    }   
            } 
        }
    }
} 

最短路径(Dijkstra)

/*==================================================*\ 
 | Dijkstra数组实现 O(N^2)
 | Dijkstra --- 数组实现(在此基础上可直接改为STL的Queue实现) 
 | lowcost[] --- beg到其他点的近距离
 | path[] -- beg为根展开的树,记录父结点 
\*==================================================*/ 
#define INF 0x03F3F3F3F 
const int N; 
int path[N], vis[N]; 
void Dijkstra(int cost[][N], int lowcost[N], int n, int beg) {  
    int i, j, min;  
    memset(vis, 0, sizeof(vis));  
    vis[beg] = 1;  
    for (i=0; i<n; i++) {   
        lowcost[i] = cost[beg][i]; 
        path[i] = beg;  
    }  
    lowcost[beg] = 0;  
    path[beg] = -1; // 树根的标记  
    int pre = beg;  
    for (i=1; i<n; i++) {         
        min = INF;  
        for (j=0; j<n; j++)          
        // 下面的加法可能导致溢出,INF不能取太大    
            if (vis[j]==0 && lowcost[pre]+cost[pre][j]<lowcost[j]) {     
                lowcost[j] = lowcost[pre] + cost[pre][j];     
                path[j] = pre;    
        }   
        for (j=0; j<n; j++)    
            if (vis[j] == 0 && lowcost[j] < min){     
                min = lowcost[j]; 
                pre = j;    
        }         
        vis[pre] = 1;  
    } 
} 
/*==================================================*\ 
 | Dijkstra O(E * log E) 
 | INIT: 调用init(nv, ne)读入边并初始化; 
 | CALL: dijkstra(n, src); dist[i]为src到i的短距离
 \*==================================================*/ 
#define typec int              // type of cost const 
typec inf = 0x3f3f3f3f;        // max of cost 
typec cost[E], dist[V]; 
int e, pnt[E], nxt[E], head[V], prev[V], vis[V]; 
struct qnode {  
    int v; typec c;  
    qnode (int vv = 0, typec cc = 0) : v(vv), c(cc) {}  
    bool operator < (const qnode& r) const { return c>r.c; } 
}; 
void dijkstra(int n, const int src) {  
 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值